├── lib ├── ActiveRecord │ └── Connection.php └── ActiveRecord.php ├── example └── example.php └── README.textile /lib/ActiveRecord/Connection.php: -------------------------------------------------------------------------------- 1 | getMessage()); 21 | } catch (\Exception $e) { 22 | die($e->getMessage()); 23 | } 24 | 25 | } 26 | return self::$instance; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /example/example.php: -------------------------------------------------------------------------------- 1 | array('class'=>'User') 16 | ); 17 | static $hasMany = array( 18 | 'tags' => array('class'=>'Tag','joinTable'=>'post_tag') 19 | ); 20 | } 21 | 22 | class User extends ActiveRecord 23 | { 24 | public $posts; 25 | static $hasMany = array( 26 | 'posts' => array('class'=>'Post') 27 | ); 28 | } 29 | 30 | class Tag extends ActiveRecord 31 | { 32 | static $hasMany = array( 33 | 'posts' => array('class'=>'Post','joinTable'=>'post_tag') 34 | ); 35 | 36 | } 37 | 38 | var_dump(User::find(1)->posts); 39 | 40 | // membuat data baru 41 | 42 | $user = new User(); 43 | $user->name = 'Ata'; 44 | $user->email = 'ata@javan.co.id'; 45 | $user->save(); 46 | 47 | // memperbaharui data 48 | $user = User::find(2);// mengambil data dengan id =2 49 | $user->name = 'Seseorang Lagi'; 50 | $user->save();// menyimpanya kembali 51 | 52 | // Mengambil data dengan relasi 53 | 54 | $users = User::all(array('limit'=>2)); 55 | 56 | foreach($users as $user){ 57 | echo 'nama: '. $user->name ."
\n"; 58 | echo 'email: '. $user->name ."
\n"; 59 | echo 'posts:
'; 60 | foreach($user->posts as $post){//relasi 'hasMany' 61 | echo ' title' . $post->title . "
\n"; 62 | echo ' content' . $post->content . "
\n"; 63 | foreach($post->tags as $tag) { 64 | echo ' tag: '.$tag->name . "
\n"; 65 | } 66 | } 67 | 68 | } 69 | 70 | -------------------------------------------------------------------------------- /README.textile: -------------------------------------------------------------------------------- 1 | h1. SAMPLE CODE: 2 | 3 |
 4 |  array('class'=>'User')
19 |     );
20 |     static $hasMany = array(
21 |         'tags' => array('class'=>'Tag','joinTable'=>'post_tag')
22 |     );
23 | }
24 | 
25 | class User extends ActiveRecord
26 | {
27 |     public $posts;
28 |     static $hasMany = array(
29 |         'posts' => array('class'=>'Post')
30 |     );
31 | }
32 | 
33 | class Tag extends ActiveRecord
34 | {
35 |     static $hasMany = array(
36 |         'posts' => array('class'=>'Post','joinTable'=>'post_tag')
37 |     );
38 |     
39 | }
40 | 
41 | var_dump(User::find(1)->posts);
42 | 
43 | // membuat data baru
44 | 
45 | $user = new User();
46 | $user->name = 'Ata';
47 | $user->email = 'ata@javan.co.id';
48 | $user->save();
49 | 
50 | // memperbaharui data
51 | $user = User::find(2);// mengambil data dengan id =2
52 | $user->name = 'Seseorang Lagi';
53 | $user->save();// menyimpanya kembali
54 | 
55 | // Mengambil data dengan relasi
56 | 
57 | $users = User::all(array('limit'=>2));
58 |  
59 | foreach($users as $user){
60 |     echo 'nama: '. $user->name ."
\n"; 61 | echo 'email: '. $user->name ."
\n"; 62 | echo 'posts:
'; 63 | foreach($user->posts as $post){//relasi 'hasMany' 64 | echo ' title' . $post->title . "
\n"; 65 | echo ' content' . $post->content . "
\n"; 66 | foreach($post->tags as $tag) { 67 | echo ' tag: '.$tag->name . "
\n"; 68 | } 69 | } 70 | 71 | } 72 | 73 | 74 |
75 | -------------------------------------------------------------------------------- /lib/ActiveRecord.php: -------------------------------------------------------------------------------- 1 | setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); 25 | } 26 | 27 | public static function getDb() 28 | { 29 | return self::$db; 30 | } 31 | 32 | public static function getTable() 33 | { 34 | if (!isset(static::$table)) { 35 | $short_class = static::getReflection()->getShortName(); 36 | return strtolower(preg_replace('~(?<=\\w)([A-Z])~', '_$1', $short_class)); 37 | } 38 | return static::$table; 39 | } 40 | 41 | public static function getReflection() 42 | { 43 | return new \ReflectionClass(get_called_class()); 44 | } 45 | 46 | public static function getPrimaryKey() 47 | { 48 | if (!isset(static::$primaryKey)) { 49 | return 'id'; 50 | } else { 51 | return static::$primaryKey; 52 | } 53 | } 54 | 55 | /** return array('id','name','email') 56 | */ 57 | public static function getColumns() 58 | { 59 | if(isset(self::$columns[get_called_class()])) { 60 | return self::$columns[get_called_class()]; 61 | } 62 | 63 | $table = static::getTable(); 64 | $sql = "SHOW COLUMNS FROM $table"; 65 | $statement = self::$db->prepare($sql); 66 | $statement->execute(); 67 | $dbcolumns = $statement->fetchAll(\PDO::FETCH_ASSOC); 68 | $columns = array(); 69 | foreach ($dbcolumns as $dc) { 70 | $columns[] = $dc['Field']; 71 | } 72 | return self::$columns[get_called_class()] = $columns; 73 | 74 | } 75 | 76 | protected static function unsetRelationProperties($object) 77 | { 78 | $class = get_class($object); 79 | if (isset(static::$belongsTo)){ 80 | foreach (array_keys(static::$belongsTo) as $property) { 81 | if (property_exists($object,$property)){ 82 | unset($object->$property); 83 | } 84 | } 85 | } 86 | if (isset(static::$hasOne)){ 87 | foreach (array_keys(static::$hasOne) as $property) { 88 | if (property_exists($object,$property)) { 89 | unset($object->$property); 90 | } 91 | } 92 | } 93 | if (isset(static::$hasMany)){ 94 | foreach (array_keys(static::$hasMany) as $property) { 95 | if(property_exists($object,$property)){ 96 | unset($object->$property); 97 | } 98 | } 99 | } 100 | 101 | } 102 | 103 | public function __get($property) 104 | { 105 | 106 | if(isset(static::$belongsTo) && array_key_exists($property,static::$belongsTo)) { 107 | return $this->getBelongsToProperty($property); 108 | } 109 | if(isset(static::$hasOne) && array_key_exists($property,static::$hasOne)) { 110 | return $this->getHasOneProperty($property); 111 | } 112 | 113 | if(isset(static::$hasMany) && array_key_exists($property,static::$hasMany)) { 114 | return $this->getHasManyProperty($property); 115 | } 116 | 117 | } 118 | 119 | 120 | protected function getBelongsToProperty($property) 121 | { 122 | if(isset(static::$belongsTo) && array_key_exists($property,static::$belongsTo)) { 123 | $primaryKey = static::getPrimaryKey(); 124 | $ref = static::$belongsTo[$property]; 125 | $associationClass = $ref['class']; 126 | $foreignKey = isset($ref['foreignKey'])?$ref['foreignKey']:$property . '_id'; 127 | return $this->$property = $associationClass::find($this->$foreignKey); 128 | } 129 | return false; 130 | } 131 | 132 | protected function getHasOneProperty($property) 133 | { 134 | if(isset(static::$hasOne) && array_key_exists($property,static::$hasOne)) { 135 | $ref = static::$hasOne[$property]; 136 | $class = $ref['class']; 137 | $foreignKey = isset($ref['foreignKey'])?$ref['foreignKey']: static::getTable() . '_id'; 138 | $primaryKey = static::getPrimaryKey(); 139 | $table = $class::getTable(); 140 | $statement = $class::query("SELECT * FROM $table WHERE $foreignKey = ? ", 141 | array($this->$primaryKey)); 142 | return $this->$propery = $statement->fetch(); 143 | } 144 | return false; 145 | } 146 | 147 | protected function getHasManyProperty($property) 148 | { 149 | if(isset(static::$hasMany) && array_key_exists($property,static::$hasMany)) { 150 | $ref = static::$hasMany[$property]; 151 | $class = $ref['class']; 152 | $foreignKey = isset($ref['foreignKey'])?$ref['foreignKey']: static::getTable() . '_id'; 153 | $associationTable = $class::getTable(); 154 | $primaryKey = static::getPrimaryKey(); 155 | 156 | if (isset($ref['joinTable'])) { 157 | $associationForeignKey = isset($ref['associationForeignKey'])? 158 | $ref['associationForeignKey']:$class::getTable() . '_id'; 159 | $associationPrimaryKey = $class::getPrimaryKey(); 160 | $joinTable = $ref['joinTable']; 161 | 162 | $statement = $class::query("SELECT * FROM $associationTable 163 | WHERE $associationPrimaryKey IN ( 164 | SELECT $associationForeignKey 165 | FROM $joinTable 166 | WHERE $foreignKey = ? 167 | )",array($this->$primaryKey)); 168 | 169 | return $this->$property = $statement->fetchAll(); 170 | 171 | } 172 | $statement = $class::query("SELECT * FROM $associationTable 173 | WHERE $foreignKey = ? ", 174 | array($this->$primaryKey)); 175 | return $this->$property = $statement->fetchAll(); 176 | 177 | } 178 | return false; 179 | } 180 | 181 | public function __set($property,$value) 182 | { 183 | if(isset(static::$belongsTo) && array_key_exists($property,static::$belongsTo)) { 184 | $ref = static::$belongsTo[$property]; 185 | $class = $ref['class']; 186 | $foreignKey = isset($ref['foreignKey'])?$ref['foreignKey']:$property . '_id'; 187 | $primaryKey = $class::getPrimaryKey(); 188 | //return $this->$property = $class::find($this->$foreignKey); 189 | $this->$foreignKey = $value->$primaryKey; 190 | 191 | } 192 | $this->$property = $value; 193 | } 194 | 195 | 196 | 197 | 198 | //======Retriving data method======== 199 | 200 | /** 201 | * return @type PDOStatement 202 | */ 203 | public static function query($query, $params = array()) 204 | { 205 | $class = get_called_class(); 206 | try { 207 | $statement = self::$db->prepare($query); 208 | $object = new $class(); 209 | static::unsetRelationProperties($object); 210 | $statement->setFetchMode(\PDO::FETCH_INTO,$object); 211 | $statement->execute($params); 212 | return self::$statement[$class] = $statement; 213 | } catch (PDOStatement $e) { 214 | die($e->getMessage()); 215 | } 216 | } 217 | /** 218 | * $options = array( 219 | * 'select' => 'name,message', 220 | * 'where' => '', 221 | * 'limit' => 222 | * 'offset' => 223 | * 'order' => '' 224 | * ); 225 | */ 226 | protected function findAll($options = array()) 227 | { 228 | $select = 'SELECT *'; 229 | $limit = ''; 230 | $offset = ''; 231 | $where = ''; 232 | $order = ''; 233 | 234 | if (isset($options['select'])) { 235 | $select = 'SELECT ' . $options['select']; 236 | if (count(array_keys(array_map(function($v){return trim($v);}, 237 | explode(',',$options['select'])),static::getPrimaryKey())) === 0) { 238 | 239 | $select .= ', ' . static::getPrimaryKey(); 240 | } 241 | } 242 | if (isset($options['where'])) { 243 | $where = 'where ' . $options['where']; 244 | } 245 | 246 | if (isset($options['order'])) { 247 | $offset = 'ORDER BY ' . $options['order']; 248 | } 249 | 250 | if (isset($options['limit'])) { 251 | $limit = 'LIMIT ' . $options['limit']; 252 | } 253 | 254 | if (isset($options['offset'])) { 255 | $offset = 'OFFSET ' . $options['offset']; 256 | } 257 | 258 | $table = static::getTable(); 259 | 260 | return static::query("$select from $table $where $order $limit $offset"); 261 | 262 | } 263 | 264 | 265 | public static function all($options = array()) 266 | { 267 | return static::findAll($options)->fetchAll(); 268 | } 269 | 270 | public static function first($options = array()){ 271 | $options['limit'] = '1'; 272 | return static::findAll($options)->fetch(); 273 | } 274 | /** 275 | * find(1) --> return single object with id = 1 276 | * find(1,2) --> return array of object with id = 1 and 2 277 | * find('name','Ata') --> return array objek with field 'name' is 'Ata' 278 | */ 279 | 280 | 281 | public static function find() 282 | { 283 | $class = get_called_class(); 284 | if (func_num_args() === 1) { 285 | return static::findByPrimaryKey(func_get_arg(0)); 286 | } 287 | if (property_exists($class,func_get_arg(0)) && func_num_args() > 1) { 288 | 289 | } else { 290 | return call_user_func_array(array($class,'findByPrimaryKeys'), 291 | func_get_args()); 292 | } 293 | 294 | } 295 | 296 | protected static function findByPrimaryKey($id) 297 | { 298 | $table = static::getTable(); 299 | $primaryKey = static::getPrimaryKey(); 300 | $statement = static::query("SELECT * FROM $table 301 | WHERE $primaryKey = :id", 302 | array('id' => $id)); 303 | return $statement->fetch(); 304 | 305 | } 306 | 307 | protected static function findByPrimaryKeys() 308 | { 309 | $ids = func_get_args(); 310 | $q1 = implode(',',array_map(function($v){return '?';},$ids)); 311 | 312 | $table = static::getTable(); 313 | $primaryKey = static::getPrimaryKey(); 314 | $statement = static::query("SELECT * FROM $table 315 | WHERE $primaryKey in ($q1)",$ids); 316 | return $statement->fetchAll(); 317 | } 318 | 319 | 320 | /* ===== Saving data =========*/ 321 | public function save() 322 | { 323 | $primaryKey = static::getPrimaryKey(); 324 | $class = get_class($this); 325 | 326 | if(isset($this->$primaryKey)){ 327 | if($this->$primaryKey !== null) { 328 | return static::update($this); 329 | } else { 330 | return static::insert($this); 331 | } 332 | } else { 333 | return static::insert($this); 334 | } 335 | } 336 | 337 | protected static function update($object) 338 | { 339 | $table = static::getTable(); 340 | $primaryKey = static::getPrimaryKey(); 341 | $sets = array(); 342 | $params = array(); 343 | foreach (static::getColumns() as $c) { 344 | if(property_exists($object,$c) && $object->$c !== null){ 345 | $sets[] = "$c = :$c "; 346 | $params[$c] = $object->$c; 347 | } 348 | } 349 | 350 | $params['primaryKey'] = $object->$primaryKey; 351 | $sets = join(',',$sets); 352 | $statement = self::$db->prepare("UPDATE $table SET $sets 353 | WHERE $primaryKey = :primaryKey"); 354 | return $statement->execute($params); 355 | 356 | } 357 | 358 | protected static function insert($object) 359 | { 360 | $table = static::getTable(); 361 | $columns = array(); 362 | $values = array(); 363 | $params = array(); 364 | foreach (static::getColumns() as $c) { 365 | if(property_exists($object,$c) && $object->$c !== null){ 366 | $columns[] = $c; 367 | $values[] = ':'.$c; 368 | $params[$c] = $object->$c; 369 | } 370 | } 371 | 372 | $sql_columns = join(',',$columns); 373 | $sql_values = join(',',$values); 374 | $statement = self::$db->prepare("INSERT INTO $table($sql_columns) VALUES($sql_values)"); 375 | return $statement->execute($params); 376 | } 377 | 378 | 379 | //====== DESTROYING DATA ========== 380 | /** 381 | * destroy(1) -> destroy with primary key = 1 382 | * destroy(1,2,3) -> destroy with primary is 1,2 and 3 383 | */ 384 | public static function destroy($id) 385 | { 386 | $table = static::getTable(); 387 | $primaryKey = static::getPrimaryKey(); 388 | if(func_num_args() == 1){ 389 | $statement = self::$db->prepare("DELETE from $table WHERE $primaryKey = ?"); 390 | return $statement->execute(array($id)); 391 | } else { 392 | $ids = func_get_args(); 393 | $q1 = implode(',',array_map(function($v){return '?';},$ids)); 394 | 395 | $statement = self::$db->prepare("DELETE from $table WHERE $primaryKey IN ($q1)"); 396 | return $statement->execute($ids); 397 | } 398 | 399 | return false; 400 | } 401 | 402 | public function delete() 403 | { 404 | $primaryKey = static::getPrimaryKey(); 405 | $class = get_class($this); 406 | 407 | if (isset($this->$primaryKey) && $this->$primaryKey !== null) { 408 | return static::destroy($this->$primaryKey); 409 | } 410 | return false; 411 | } 412 | } 413 | --------------------------------------------------------------------------------