dbObject.md 10 KB
Newer Older
1 2 3
dbObject - model implementation on top of the MysqliDb.

Please note that this library is not pretending to be a full stack ORM, but simply an OOP wrapper for `mysqlidb`.
4 5

<hr>
6 7

### Initialization
Alexander Butenko's avatar
Alexander Butenko committed
8

9
Include mysqlidb and dbObject classes. If you want to use model autoloading instead of manually including them in the scripts use `autoload()` method.
10
```php
11 12
require_once("libs/MysqliDb.php");
require_once("libs/dbObject.php");
13 14

// db instance
15
$db = new Mysqlidb('localhost', 'user', '', 'testdb');
16
// enable class autoloading
17
dbObject::autoload("models");
18
```
Alexander Butenko's avatar
Alexander Butenko committed
19

20
Each database table could be easily mapped into a dbObject instance.  If you do not want to create model for a simple table its object could be simply created with a `table()` method.
21
```php
22
$user = dbObject::table("users");
23 24
```

25
Otherwise basic model should be declared as:
26 27 28
```php
class user extends dbObject {}
```
29
In case autoload is set to 'models' directory, the filename should be models/user.php
30

31
Class will be related to 'user' table. To change the table name, define correct name in the `$dbTable` variable:
32 33 34 35 36

```php
    protected $dbTable = "users";
```

37 38
Both objects created throw new class file creation of with `table()` method will have the same set of methods available. Only exception is that relations, validation or custom model methods
will not be working with an objects created with `table()` method.
39 40


41
### Selects
42
Retrieving objects from the database is pretty much the same process as a mysqliDb `get()`/`getOne()` methods without a need to specify table name. All mysqlidb functions like `where()`, `orWhere()`, `orderBy()`, `join()`, etc. are supported.
43

44
## Retrieving All Records
Alexander Butenko's avatar
Alexander Butenko committed
45

46
```php
47 48
//$users = dbObject::table('users')->get();
$users = user::get();
49
foreach ($users as $u) {
50
  echo $u->login;
51 52
}
```
53 54 55

## Using Where Condition And A Limit
```php
56
$users = user::where("login", "demo")->get(Array (10, 20));
57
foreach ($users as $u) ...
58 59
```

60
## Retrieving A Model By Primary Key
61 62

```php
63 64
//$user = dbObject::table('users')->byId(1);
$user = user::byId(1);
65 66 67 68 69 70 71 72 73 74
echo $user->login;
```

dbObject will also assume that each table has a primary key column named "id". You may define a primaryKey property to override this assumption.

```php
  protected $primaryKey = "userId";
```


75
### Insert Row
76
1. OOP Way. Just create new object of a needed class, fill it in and call `save()` method. Save will return
77 78
record id in case of success and false in case if insert will fail.
```php
79
//$user = dbObject::table('users');
80 81 82
$user = new user;
$user->login = 'demo';
$user->password = 'demo';
83
$id = $user->save();
84 85 86
if ($id)
  echo "user created with id = " . $id;
```
Alexander Butenko's avatar
Alexander Butenko committed
87

88 89
2. Using arrays
```php
90
$data = Array('login' => 'demo',
91 92
        'password' => 'demo');
$user = new user ($data);
93
$id = $user->save();
94
if ($id == null) {
95
    print_r($user->errors);
96 97 98 99 100
    echo $db->getLastError;
} else
    echo "user created with id = " . $id;
```

Alexander Butenko's avatar
Alexander Butenko committed
101 102
3. Multisave

103 104 105 106 107 108 109 110 111
```php
$user = new user;
$user->login = 'demo';
$user->pass = 'demo';

$p = new product;
$p->title = "Apples";
$p->price = 0.5;
$p->seller = $user;
112
$p->save();
113 114
```

115
After `save()` is called, both new objects (user and product) will be saved.
116 117


118
### Update
119
To update model properties just set them and call `save()` method. Values that need to be changed could be passed as an array to the `save()` method as well.
120 121

```php
122
$user = user::byId(1);
123
$user->password = 'demo2';
124
$user->save();
125 126
```
```php
127 128 129
$data = Array('password', 'demo2');
$user = user::byId(1);
$user->save($data);
130 131
```

132
### Delete
133
Use `delete()` method on any loaded object.
134
```php
135 136
$user = user::byId(1);
$user->delete();
137 138
```

139
### Relations
140
Currently dbObject supports only `hasMany` and `hasOne` relations. To use them declare `$relations` array in the model class.
141 142
After that you can get related object via variable names defined as keys.

143
## hasOne example:
144
```php
145 146
    protected $relations = Array(
        'person' => Array("hasOne", "person", 'id');
147
    );
148 149 150

    ...

151
    $user = user::byId(1);
152
    // sql: select * from users where id = $personValue
153
    echo $user->person->firstName . " " . $user->person->lastName . " have the following products:\n";
154
    // one more sql: select * from person where id=x
155
```
156
Please note, that following way of querying will execute 2 sql queries:
157 158
1. `select * from users where id=1`
2. `select * from person where id=x`
159

160
To optimize this into single select join query use `with()` method.
161
```php
162
   $user = user::with('person')->byId(1);
163 164 165
   // sql: select * from users left join person on person.id = users.id wher id = 1;
    echo $user->person->firstName . " " . $user->person->lastName . " have the following products:\n";
```
166

167
## hasMany example:
168
In the `hasMany` array should be defined the target object name (product in example) and a relation key (userid).
169
```php
170 171
    protected $relations = Array(
        'products' => Array("hasMany", "product", 'userid')
172 173 174 175
    );

    ...

176
    $user = user::byId(1);
177
    // sql: select * from $product_table where userid = $userPrimaryKey
178 179 180 181
    foreach ($user->products as $p) {
            echo $p->title;
    }
```
182 183 184

### Joining tables
```php
185 186
$depts = product::join('user');
$depts = product::join('user', 'productid');
187 188
```

189
First parameter will set an object which should be joined. Second paramter will define a key. Default key is `$objectName+'Id'`
190 191


192
NOTE: Objects returned with `join()` will not save changes to a joined properties. For this you can use relationships.
193

194
### Timestamps
195
Library provides a transparent way to set timestamps of an object creation and its modification:
196
To enable that define `$timestamps` array as follows:
197 198 199
```php
protected $timestamps = Array ('createdAt', 'updatedAt');
```
200
Field names can't be changed.
201

202
### Array Fields
203 204
dbObject can automatically handle array type of values. Optionaly you can store arrays in json encoded or in pipe delimited format.
To enable automatic json serialization of the field define `$jsonFields` array in your modal:
Alexander Butenko's avatar
Alexander Butenko committed
205
```php
206
    protected $jsonFields = Array('options');
Alexander Butenko's avatar
Alexander Butenko committed
207
```
208
To enable pipe delimited storage of the field, define `$arrayFields` array in your modal:
Alexander Butenko's avatar
Alexander Butenko committed
209
```php
210
    protected $arrayFields = Array('sections');
Alexander Butenko's avatar
Alexander Butenko committed
211
```
212 213
The following code will now store `'options'` variable as a json string in the database, and will return an array on load.
Same with the `'sections'` variable except that it will be stored in pipe delimited format.
Alexander Butenko's avatar
Alexander Butenko committed
214 215 216
```php
    $user = new user;
    $user->login = 'admin';
217 218 219
    $user->options = Array('canReadNews', 'canPostNews', 'canDeleteNews');
    $user->sections = Array('news', 'companyNews');
    $user->save();
Alexander Butenko's avatar
Alexander Butenko committed
220
    ...
221 222
    $user = user::byId(1);
    print_r($user->options);
Alexander Butenko's avatar
Alexander Butenko committed
223 224
```

225
### Validation and Error checking
226 227
Before saving and updating the row, dbObject does input validation. In case validation rules are set but their criteria is
not met, then `save()` will return an error with its description. For example:
228 229 230 231
```php
$id = $user->save();
if (!$id) {
    // show all validation errors
232
    print_r($user->errors);
233 234 235 236 237
    echo $db->getLastQuery();
    echo $db->getLastError();
}
echo "user were created with id" . $id;
```
238
Validation rules must be defined in `$dbFields` array.
239
```php
240 241 242 243 244 245
  protected $dbFields = Array(
    'login' => Array('text', 'required'),
    'password' => Array('text'),
    'createdAt' => Array('datetime'),
    'updatedAt' => Array('datetime'),
    'custom' => Array('/^test/'),
246 247 248 249 250
  );
```
First parameter is a field type. Types could be the one of following: text, bool, int, datetime or a custom regexp.
Second parameter is 'required' and its defines that following entry field be always defined.

251
**NOTE:** All variables which are not defined in the `$dbFields` array will be ignored from insert/update statement.
Alexander Butenko's avatar
Alexander Butenko committed
252

253
### Using array as a return value
254
dbObject can return its data as array instead of object. To do that, the `ArrayBuilder()` function should be used in the beginning of the call.
255
```php
256
    $user = user::ArrayBuilder()->byId(1);
257 258
    echo $user['login'];

259
    $users = user::ArrayBuilder()->orderBy("id", "desc")->get();
260 261 262 263
    foreach ($users as $u)
        echo $u['login'];
```

264
The following call will return data only of the called instance without any relations data. Use `with()` function to include relation data as well.
265
```php
266
    $user = user::ArrayBuilder()->with("product")->byId(1);
267 268
    print_r ($user['products']);
```
269

270
### Using json as a return value
271
Together with `ArrayBuilder()` and `ObjectBuilder()`, dbObject can also return a result in json format to avoid extra coding.
272
```php
273
    $userjson = user::JsonBuilder()->with("product")->byId(1);
274
```
275
### Object serialization
276 277 278 279

Object could be easily converted to a json string or an array.

```php
280
    $user = user::byId(1);
281 282 283
    // echo will display json representation of an object
    echo $user;
    // userJson will contain json representation of an object
284
    $userJson = $user->toJson();
285
    // userArray will contain array representation of an object
286
    $userArray = $user->toArray();
287 288
```

289
### Pagination
290 291 292 293 294 295 296 297 298
Use paginate() instead of get() to fetch paginated result
```php
$page = 1;
// set page limit to 2 results per page. 20 by default
product::$pageLimit = 2;
$products = product::arraybuilder()->paginate($page);
echo "showing $page out of " . product::$totalPages;

```
299

300
### Hidden Fields
301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334
Sometimes it's important to block some fields that can be accessed from outside the model class (for example, the user password).

To block the access to certain fields using the `->` operator, you can declare the  `$hidden` array into the model class. This array holds column names that can't be accessed with the `->` operator.

For example:

```php
class User extends dbObject {
    protected $dbFields = array(
        'username' => array('text', 'required'),
        'password' => array('text', 'required'),
        'is_admin' => array('bool'),
        'token' => array('text')
    );

    protected $hidden = array(
        'password', 'token'
    );
}
```

If you try to:
```php
echo $user->password;
echo $user->token;
```

Will return `null`, and also:
```php
$user->password = "my-new-password";
```

Won't change the current `password` value.

335
### Examples
336

Alexander Butenko's avatar
Alexander Butenko committed
337
Please look for a use examples in <a href='tests/dbObjectTests.php'>tests file</a> and test models inside the <a href='tests/models/'>test models</a> directory