[ Index ] |
|
Code source de PHP PEAR 1.4.5 |
1 <?php 2 3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ 4 5 /** 6 * Provides an object interface to a table row 7 * 8 * PHP versions 4 and 5 9 * 10 * LICENSE: This source file is subject to version 3.0 of the PHP license 11 * that is available through the world-wide-web at the following URI: 12 * http://www.php.net/license/3_0.txt. If you did not receive a copy of 13 * the PHP License and are unable to obtain it through the web, please 14 * send a note to license@php.net so we can mail you a copy immediately. 15 * 16 * @category Database 17 * @package DB 18 * @author Stig Bakken <stig@php.net> 19 * @copyright 1997-2005 The PHP Group 20 * @license http://www.php.net/license/3_0.txt PHP License 3.0 21 * @version CVS: $Id: storage.php,v 1.22 2005/07/10 13:38:51 danielc Exp $ 22 * @link http://pear.php.net/package/DB 23 */ 24 25 /** 26 * Obtain the DB class so it can be extended from 27 */ 28 require_once 'DB.php'; 29 30 /** 31 * Provides an object interface to a table row 32 * 33 * It lets you add, delete and change rows using objects rather than SQL 34 * statements. 35 * 36 * @category Database 37 * @package DB 38 * @author Stig Bakken <stig@php.net> 39 * @copyright 1997-2005 The PHP Group 40 * @license http://www.php.net/license/3_0.txt PHP License 3.0 41 * @version Release: 1.7.9 42 * @link http://pear.php.net/package/DB 43 */ 44 class DB_storage extends PEAR 45 { 46 // {{{ properties 47 48 /** the name of the table (or view, if the backend database supports 49 updates in views) we hold data from */ 50 var $_table = null; 51 52 /** which column(s) in the table contains primary keys, can be a 53 string for single-column primary keys, or an array of strings 54 for multiple-column primary keys */ 55 var $_keycolumn = null; 56 57 /** DB connection handle used for all transactions */ 58 var $_dbh = null; 59 60 /** an assoc with the names of database fields stored as properties 61 in this object */ 62 var $_properties = array(); 63 64 /** an assoc with the names of the properties in this object that 65 have been changed since they were fetched from the database */ 66 var $_changes = array(); 67 68 /** flag that decides if data in this object can be changed. 69 objects that don't have their table's key column in their 70 property lists will be flagged as read-only. */ 71 var $_readonly = false; 72 73 /** function or method that implements a validator for fields that 74 are set, this validator function returns true if the field is 75 valid, false if not */ 76 var $_validator = null; 77 78 // }}} 79 // {{{ constructor 80 81 /** 82 * Constructor 83 * 84 * @param $table string the name of the database table 85 * 86 * @param $keycolumn mixed string with name of key column, or array of 87 * strings if the table has a primary key of more than one column 88 * 89 * @param $dbh object database connection object 90 * 91 * @param $validator mixed function or method used to validate 92 * each new value, called with three parameters: the name of the 93 * field/column that is changing, a reference to the new value and 94 * a reference to this object 95 * 96 */ 97 function DB_storage($table, $keycolumn, &$dbh, $validator = null) 98 { 99 $this->PEAR('DB_Error'); 100 $this->_table = $table; 101 $this->_keycolumn = $keycolumn; 102 $this->_dbh = $dbh; 103 $this->_readonly = false; 104 $this->_validator = $validator; 105 } 106 107 // }}} 108 // {{{ _makeWhere() 109 110 /** 111 * Utility method to build a "WHERE" clause to locate ourselves in 112 * the table. 113 * 114 * XXX future improvement: use rowids? 115 * 116 * @access private 117 */ 118 function _makeWhere($keyval = null) 119 { 120 if (is_array($this->_keycolumn)) { 121 if ($keyval === null) { 122 for ($i = 0; $i < sizeof($this->_keycolumn); $i++) { 123 $keyval[] = $this->{$this->_keycolumn[$i]}; 124 } 125 } 126 $whereclause = ''; 127 for ($i = 0; $i < sizeof($this->_keycolumn); $i++) { 128 if ($i > 0) { 129 $whereclause .= ' AND '; 130 } 131 $whereclause .= $this->_keycolumn[$i]; 132 if (is_null($keyval[$i])) { 133 // there's not much point in having a NULL key, 134 // but we support it anyway 135 $whereclause .= ' IS NULL'; 136 } else { 137 $whereclause .= ' = ' . $this->_dbh->quote($keyval[$i]); 138 } 139 } 140 } else { 141 if ($keyval === null) { 142 $keyval = @$this->{$this->_keycolumn}; 143 } 144 $whereclause = $this->_keycolumn; 145 if (is_null($keyval)) { 146 // there's not much point in having a NULL key, 147 // but we support it anyway 148 $whereclause .= ' IS NULL'; 149 } else { 150 $whereclause .= ' = ' . $this->_dbh->quote($keyval); 151 } 152 } 153 return $whereclause; 154 } 155 156 // }}} 157 // {{{ setup() 158 159 /** 160 * Method used to initialize a DB_storage object from the 161 * configured table. 162 * 163 * @param $keyval mixed the key[s] of the row to fetch (string or array) 164 * 165 * @return int DB_OK on success, a DB error if not 166 */ 167 function setup($keyval) 168 { 169 $whereclause = $this->_makeWhere($keyval); 170 $query = 'SELECT * FROM ' . $this->_table . ' WHERE ' . $whereclause; 171 $sth = $this->_dbh->query($query); 172 if (DB::isError($sth)) { 173 return $sth; 174 } 175 $row = $sth->fetchRow(DB_FETCHMODE_ASSOC); 176 if (DB::isError($row)) { 177 return $row; 178 } 179 if (!$row) { 180 return $this->raiseError(null, DB_ERROR_NOT_FOUND, null, null, 181 $query, null, true); 182 } 183 foreach ($row as $key => $value) { 184 $this->_properties[$key] = true; 185 $this->$key = $value; 186 } 187 return DB_OK; 188 } 189 190 // }}} 191 // {{{ insert() 192 193 /** 194 * Create a new (empty) row in the configured table for this 195 * object. 196 */ 197 function insert($newpk) 198 { 199 if (is_array($this->_keycolumn)) { 200 $primarykey = $this->_keycolumn; 201 } else { 202 $primarykey = array($this->_keycolumn); 203 } 204 settype($newpk, "array"); 205 for ($i = 0; $i < sizeof($primarykey); $i++) { 206 $pkvals[] = $this->_dbh->quote($newpk[$i]); 207 } 208 209 $sth = $this->_dbh->query("INSERT INTO $this->_table (" . 210 implode(",", $primarykey) . ") VALUES(" . 211 implode(",", $pkvals) . ")"); 212 if (DB::isError($sth)) { 213 return $sth; 214 } 215 if (sizeof($newpk) == 1) { 216 $newpk = $newpk[0]; 217 } 218 $this->setup($newpk); 219 } 220 221 // }}} 222 // {{{ toString() 223 224 /** 225 * Output a simple description of this DB_storage object. 226 * @return string object description 227 */ 228 function toString() 229 { 230 $info = strtolower(get_class($this)); 231 $info .= " (table="; 232 $info .= $this->_table; 233 $info .= ", keycolumn="; 234 if (is_array($this->_keycolumn)) { 235 $info .= "(" . implode(",", $this->_keycolumn) . ")"; 236 } else { 237 $info .= $this->_keycolumn; 238 } 239 $info .= ", dbh="; 240 if (is_object($this->_dbh)) { 241 $info .= $this->_dbh->toString(); 242 } else { 243 $info .= "null"; 244 } 245 $info .= ")"; 246 if (sizeof($this->_properties)) { 247 $info .= " [loaded, key="; 248 $keyname = $this->_keycolumn; 249 if (is_array($keyname)) { 250 $info .= "("; 251 for ($i = 0; $i < sizeof($keyname); $i++) { 252 if ($i > 0) { 253 $info .= ","; 254 } 255 $info .= $this->$keyname[$i]; 256 } 257 $info .= ")"; 258 } else { 259 $info .= $this->$keyname; 260 } 261 $info .= "]"; 262 } 263 if (sizeof($this->_changes)) { 264 $info .= " [modified]"; 265 } 266 return $info; 267 } 268 269 // }}} 270 // {{{ dump() 271 272 /** 273 * Dump the contents of this object to "standard output". 274 */ 275 function dump() 276 { 277 foreach ($this->_properties as $prop => $foo) { 278 print "$prop = "; 279 print htmlentities($this->$prop); 280 print "<br />\n"; 281 } 282 } 283 284 // }}} 285 // {{{ &create() 286 287 /** 288 * Static method used to create new DB storage objects. 289 * @param $data assoc. array where the keys are the names 290 * of properties/columns 291 * @return object a new instance of DB_storage or a subclass of it 292 */ 293 function &create($table, &$data) 294 { 295 $classname = strtolower(get_class($this)); 296 $obj =& new $classname($table); 297 foreach ($data as $name => $value) { 298 $obj->_properties[$name] = true; 299 $obj->$name = &$value; 300 } 301 return $obj; 302 } 303 304 // }}} 305 // {{{ loadFromQuery() 306 307 /** 308 * Loads data into this object from the given query. If this 309 * object already contains table data, changes will be saved and 310 * the object re-initialized first. 311 * 312 * @param $query SQL query 313 * 314 * @param $params parameter list in case you want to use 315 * prepare/execute mode 316 * 317 * @return int DB_OK on success, DB_WARNING_READ_ONLY if the 318 * returned object is read-only (because the object's specified 319 * key column was not found among the columns returned by $query), 320 * or another DB error code in case of errors. 321 */ 322 // XXX commented out for now 323 /* 324 function loadFromQuery($query, $params = null) 325 { 326 if (sizeof($this->_properties)) { 327 if (sizeof($this->_changes)) { 328 $this->store(); 329 $this->_changes = array(); 330 } 331 $this->_properties = array(); 332 } 333 $rowdata = $this->_dbh->getRow($query, DB_FETCHMODE_ASSOC, $params); 334 if (DB::isError($rowdata)) { 335 return $rowdata; 336 } 337 reset($rowdata); 338 $found_keycolumn = false; 339 while (list($key, $value) = each($rowdata)) { 340 if ($key == $this->_keycolumn) { 341 $found_keycolumn = true; 342 } 343 $this->_properties[$key] = true; 344 $this->$key = &$value; 345 unset($value); // have to unset, or all properties will 346 // refer to the same value 347 } 348 if (!$found_keycolumn) { 349 $this->_readonly = true; 350 return DB_WARNING_READ_ONLY; 351 } 352 return DB_OK; 353 } 354 */ 355 356 // }}} 357 // {{{ set() 358 359 /** 360 * Modify an attriute value. 361 */ 362 function set($property, $newvalue) 363 { 364 // only change if $property is known and object is not 365 // read-only 366 if ($this->_readonly) { 367 return $this->raiseError(null, DB_WARNING_READ_ONLY, null, 368 null, null, null, true); 369 } 370 if (@isset($this->_properties[$property])) { 371 if (empty($this->_validator)) { 372 $valid = true; 373 } else { 374 $valid = @call_user_func($this->_validator, 375 $this->_table, 376 $property, 377 $newvalue, 378 $this->$property, 379 $this); 380 } 381 if ($valid) { 382 $this->$property = $newvalue; 383 if (empty($this->_changes[$property])) { 384 $this->_changes[$property] = 0; 385 } else { 386 $this->_changes[$property]++; 387 } 388 } else { 389 return $this->raiseError(null, DB_ERROR_INVALID, null, 390 null, "invalid field: $property", 391 null, true); 392 } 393 return true; 394 } 395 return $this->raiseError(null, DB_ERROR_NOSUCHFIELD, null, 396 null, "unknown field: $property", 397 null, true); 398 } 399 400 // }}} 401 // {{{ &get() 402 403 /** 404 * Fetch an attribute value. 405 * 406 * @param string attribute name 407 * 408 * @return attribute contents, or null if the attribute name is 409 * unknown 410 */ 411 function &get($property) 412 { 413 // only return if $property is known 414 if (isset($this->_properties[$property])) { 415 return $this->$property; 416 } 417 $tmp = null; 418 return $tmp; 419 } 420 421 // }}} 422 // {{{ _DB_storage() 423 424 /** 425 * Destructor, calls DB_storage::store() if there are changes 426 * that are to be kept. 427 */ 428 function _DB_storage() 429 { 430 if (sizeof($this->_changes)) { 431 $this->store(); 432 } 433 $this->_properties = array(); 434 $this->_changes = array(); 435 $this->_table = null; 436 } 437 438 // }}} 439 // {{{ store() 440 441 /** 442 * Stores changes to this object in the database. 443 * 444 * @return DB_OK or a DB error 445 */ 446 function store() 447 { 448 $params = array(); 449 $vars = array(); 450 foreach ($this->_changes as $name => $foo) { 451 $params[] = &$this->$name; 452 $vars[] = $name . ' = ?'; 453 } 454 if ($vars) { 455 $query = 'UPDATE ' . $this->_table . ' SET ' . 456 implode(', ', $vars) . ' WHERE ' . 457 $this->_makeWhere(); 458 $stmt = $this->_dbh->prepare($query); 459 $res = $this->_dbh->execute($stmt, $params); 460 if (DB::isError($res)) { 461 return $res; 462 } 463 $this->_changes = array(); 464 } 465 return DB_OK; 466 } 467 468 // }}} 469 // {{{ remove() 470 471 /** 472 * Remove the row represented by this object from the database. 473 * 474 * @return mixed DB_OK or a DB error 475 */ 476 function remove() 477 { 478 if ($this->_readonly) { 479 return $this->raiseError(null, DB_WARNING_READ_ONLY, null, 480 null, null, null, true); 481 } 482 $query = 'DELETE FROM ' . $this->_table .' WHERE '. 483 $this->_makeWhere(); 484 $res = $this->_dbh->query($query); 485 if (DB::isError($res)) { 486 return $res; 487 } 488 foreach ($this->_properties as $prop => $foo) { 489 unset($this->$prop); 490 } 491 $this->_properties = array(); 492 $this->_changes = array(); 493 return DB_OK; 494 } 495 496 // }}} 497 } 498 499 /* 500 * Local variables: 501 * tab-width: 4 502 * c-basic-offset: 4 503 * End: 504 */ 505 506 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 14:08:00 2007 | par Balluche grâce à PHPXref 0.7 |