Modèles
Introduction
Models are used in CakePHP applications for data access. Models most commonly represent a database table, though they can be used to access files, LDAP records, iCal events, or rows in a CSV file.
Models can also be associated in order to make data access easier. If you find that every time you fetch data with your Recipe model, you’d also like to fetch its related Author and Ingredient entries, model associations can help.
New in CakePHP is DataSources and Behaviors. DataSources form a unified foundation for CakePHP models. This allows for greater model interaction, including associations. Model behaviors provide a way to mix in functionality. Specifying behaviors for models gives you access to commonly needed data manipulation logic: things like tree pruning, upload handling, and more.
Fully functional model classes can look pretty bare:
<?php
class Ingredient extends AppModel {
var $name = 'Ingredient';
}
?>
<?phpclass Ingredient extends AppModel {var $name = 'Ingredient';}?>
Notice that CakePHP models extend a special AppModel class: the parent for all models in your application. Like the AppController (and AppHelper), this special class is a perfect place to put logic shared amongst all models. The AppModel class should be created at /app/app_model.php, and should extend the Model class.
With just a few lines of code, you have full CRUD (create, retrieve, update, delete) functionality. Most of this comes from the model’s grandparent class Model. Once you have a model defined, you can utilize it in your controller. Here’s a basic example of a model being used ($this->Ingredient) to fetch a list of Ingredient records to hand to the view:
<?php
class IngredientsController extends AppController {
function index() {
//Hand a list of all ingredients to the view:
$this->set(
'ingredients',
$this->Ingredient->findAll()
);
}
}
?>
<?phpclass IngredientsController extends AppController {function index() {//Hand a list of all ingredients to the view:$this->set('ingredients',$this->Ingredient->findAll());}}?>
Using models to fetch and save data can save you serious headaches. CakePHP models provide a standard and centralized way to approach your data store, while at the same time offering a level of security for your application.
Model classes can be expanded to include a number of attributes and methods to enhance their functionality. These attributes and methods will be explained next.
Champs "automagiques" des Modèles
CakePHP peut exécuter certaines tâches pour vous, si vous nommez convenablement quelques champs dans les tables de votre base de données.
"created" et "modified" (ou "updated")
These two fields are automatically managed by CakePHP model save() calls. A newly created row’s created field will be automatically populated, and its modified field is updated each time changes are made. Note that a field named updated will have the same behavior as the modified field.
Both these special fields need to be datetime fields, with the default value set to NULL.
Clés primaires utilisées comme UUIDs
If the primary key (‘id’ or overridden by setting $primaryKey) for a model is defined as char(36), CakePHP will automatically create a UUID to use for that field on creation.
This feature is especially helpful for applications that span multiple databases.
Attributs des Modèles
For a complete list of model attributes and their descriptions visit the CakePHP API. Check out http://api.cakephp.org/1.2/classModel.html.
The name of the database configuration this model uses. Configurations are specified in /app/config/database.php as class variables. Defaults to ‘default.’
The name of the database table this model uses. The default table used is the lower-cased, plural version of the model’s classname. Set this attribute to the name of an alternate table, or set it to false if you wish the model to have no database relation at all.
If the model is tied to a database table, this attribute holds the name of the column of the tables primary key. Defaults to ‘id’.
This attribute is used to define the field the model will use for display in scaffolding elements. When associated data is presented (i.e., which Ingredient you’d like to associate to a Recipe) scaffolding will use the row’s ID, ‘name’, or ‘title’ fields unless $displayField has been specified.
An integer specifying the number of levels you wish CakePHP to fetch associated model data in find() and findAll() operations.
Imagine your application features Groups which have many Users which in turn have many Articles. You can set $recursive to different values based on the amount of data you want back from a $this->Group->find() call:
- 0 - Cake fetches Group data
- 1 - Cake fetches a Group and its associated Users
- 2 - Cake fetches a Group, its associated Users, and the Users' associated Articles
Set it no higher than you need–having CakePHP fetch data you aren’t going to use unnecessarily slows your app.
The default ordering of data for any find operation. Possible values include:
$order = "field"
$order = "Model.field";
$order = "Model.field asc";
$order = "Model.field ASC";
$order = "Model.field DESC";
$order = array("Model.field" => "asc", "Model.field2" => "DESC");
$order = "field"$order = "Model.field";$order = "Model.field asc";$order = "Model.field ASC";$order = "Model.field DESC";$order = array("Model.field" => "asc", "Model.field2" => "DESC");
Value of the primary key ID of the record that this model is currently pointing to. If you are saving model data inside of a loop, set $id to null ($this->ModelName->id = null) in order to ready the model class for the next set of data.
The container for the model’s fetched data. While data returned from a model class is normally used as returned from a find() call, you may need to access information stored in $data inside of model callbacks.
Contains metadata describing the model’s database table fields. Each field is described by:
- name
- type (integer, string, datetime, etc.)
- null
- default value
- length
This attribute holds rules that allow the model to make data validation decisions before saving. Keys named after fields hold regex values allowing the model to try to make matches.
For more information on validation, see the Data Validation chapter later on in this manual.
The name of this model. CakePHP model names are CamelCased and singular. CakePHP users on PHP4 should always declare $name in order to avoid the quirks involved with PHP4 class-naming.
If set to true, data fetched by the model during a single request is cached. This caching is in-memory only, and only lasts for the duration of the request. Any duplicate requests for the same data is handled by the cache.
These model attributes will be covered later in this chapter. They hold arrays that define how this model is related to others.
This attribute is also covered later on. The $actsAs attribute stores the names of Behaviors this model uses.
$useDbConfig
The name of the database configuration this model uses. Configurations are specified in /app/config/database.php as class variables. Defaults to 'default'.
$useTable
The name of the database table this model uses. The default table used is the lower-cased, plural version of the model’s classname. Set this attribute to the name of an alternate table, or set it to false if you wish the model to have no database table at all.
$primaryKey
If the model is tied to a database table, this attribute holds the name of the column of the tables primary key. Defaults to 'id'.
$displayField
This attribute is used to define the field the model will use for display in scaffolding elements. When associated data is presented (i.e., which Ingredient you’d like to associate to a Recipe) scaffolding will use the row’s ID, 'name', or 'title' fields unless $displayField has been specified.
For example, if you want the 'username' field of the model to show rather than the default, include the following line of code in your model:
var $displayField = 'username';
var $displayField = 'username';
$recursive
An integer specifying the number of levels you wish CakePHP to fetch associated model data in find() and findAll() operations.
Imagine your application features Groups which belong to a domain and have many Users which in turn have many Articles. You can set $recursive to different values based on the amount of data you want back from a $this->Group->find() call:
- -1 - Cake fetches Group data only, no joins.
- 0 - Cake fetches Group data and its domain
- 1 - Cake fetches a Group, its domain and its associated Users
- 2 - Cake fetches a Group, its domain, its associated Users, and the Users' associated Articles
Set it no higher than you need–having CakePHP fetch data you aren’t going to use unnecessarily slows your app.
$order
The default ordering of data for any find operation. Possible values include:
$order = "field"
$order = "Model.field";
$order = "Model.field asc";
$order = "Model.field ASC";
$order = "Model.field DESC";
$order = array("Model.field" => "asc", "Model.field2" => "DESC");
$order = "field"$order = "Model.field";$order = "Model.field asc";$order = "Model.field ASC";$order = "Model.field DESC";$order = array("Model.field" => "asc", "Model.field2" => "DESC");
Value of the primary key ID of the record that this model is currently pointing to. If you are saving model data inside of a loop, set $id to null ($this->ModelName->id = null) in order to ready the model class for the next set of data.
$data
The container for the model’s fetched data. While data returned from a model class is normally used as returned from a find() call, you may need to access information stored in $data inside of model callbacks.
$_schema
Contains metadata describing the model’s database table fields. Each field is described by:
- name
- type (integer, string, datetime, etc.)
- null
- default value
- length
$validate
This attribute holds rules that allow the model to make data validation decisions before saving. Keys named after fields hold regex values allowing the model to try to make matches.
For more information on validation, see the Data Validation chapter later on in this manual.
$name
The name of this model. CakePHP model names are CamelCased and singular. CakePHP users on PHP4 should always declare $name in order to avoid the quirks involved with PHP4 class-naming.
$cacheQueries
If set to true, data fetched by the model during a single request is cached. This caching is in-memory only, and only lasts for the duration of the request. Any duplicate requests for the same data is handled by the cache.
$belongsTo, $hasOne, $hasMany, $hasAndBelongsToMany
These model attributes will be covered later in this chapter. They hold arrays that define how this model is related to others.
$actsAs
This attribute is also covered later on. The $actsAs attribute stores the names of Behaviors this model uses.
Méthodes du Modèle
Pour une liste complète des méthodes de modèle avec leurs descriptions, consultez l'API CakePHP : http://api.cakephp.org/1.2/classModel.html.
Récupérer vos données
Returns the specified fields up to $limit records matching $conditions (if any), start listing from page $page (default is page 1). If there are no matching fields, an empty array is returned.
The $conditions should be formed just as they would in an SQL statement: $conditions = "Pastry.type LIKE '%cake%' AND Pastry.created_on > ‘2007-01-01’", for example. Prefixing conditions with the model’s name (‘Pastry.type’ rather that just ‘type’) is always a good practice, especially when associated data is being fetched in a query.
Setting the $recursive parameter to an integer forces findAll() to fetch data according to the behavior described in the Model Attributes $recursive section outlined earlier.
Data from findAll() is returned in an array, following this basic format:
Array
(
[0] => Array
(
[ModelName] => Array
(
[id] => 83
[field1] => value1
[field2] => value2
[field3] => value3
)
[AssociatedModelName] => Array
(
[id] => 1
[field1] => value1
[field2] => value2
[field3] => value3
)
)
[1] => Array
(
[ModelName] => Array
(
[id] => 85
[field1] => value1
[field2] => value2
[field3] => value3
)
[AssociatedModelName] => Array
(
[id] => 2
[field1] => value1
[field2] => value2
[field3] => value3
)
)
)
Array([0] => Array([ModelName] => Array([id] => 83[field1] => value1[field2] => value2[field3] => value3)[AssociatedModelName] => Array([id] => 1[field1] => value1[field2] => value2[field3] => value3))[1] => Array([ModelName] => Array([id] => 85[field1] => value1[field2] => value2[field3] => value3)[AssociatedModelName] => Array([id] => 2[field1] => value1[field2] => value2[field3] => value3)))
Same as in findAll(), except that find only returns the first record matching the supplied $conditions.
These magic functions can be used as a shortcut to search your tables by a certain field. Just add the name of the field, in CamelCase format, to the end of these functions, and supply the criteria for that field as the first parameter.
| PHP5 findAllBy<x> Example | Corresponding SQL Fragment |
|---|---|
| $this->Product->findAllByOrderStatus(‘3’); | Product.order_status = 3 |
| $this->Recipe->findAllByType(‘Cookie’); | Recipe.type = ‘Cookie’ |
| $this->User->findAllByLastName(‘Anderson’); | User.last_name = ‘Anderson’ |
| $this->Cake->findById(7); | Cake.id = 7 |
| $this->User->findByUserName(‘psychic’); | User.user_name = ‘psychic’ |
PHP4 users have to use this function a little differently due to some case-insensitivity in PHP4:
| PHP4 findAllBy<x> Example | Corresponding SQL Fragment |
|---|---|
| $this->Product->findAllByOrder_status(‘3’); | Product.order_status = 3 |
| $this->Recipe->findAllByType(‘Cookie’); | Recipe.type = ‘Cookie’ |
| $this->User->findAllByLast_name(‘Anderson’); | User.last_name = ‘Anderson’ |
| $this->Cake->findById(7); | Cake.id = 7 |
| $this->User->findByUser_name(‘psychic’); | User.user_name = ‘psychic’ |
The returned result is an array formatted just as would be from find() or findAll().
Returns an array containing the neighboring models (with only the specified fields), specified by $field and $value, filtered by the SQL conditions, $conditions.
This is helpful shortcut in creating 'Previous' and 'Next' links that walk users through some ordered sequence through your model entries. It only works for numeric and date based fields.
class ImagesController extends AppController {
function view($id) {
// Say we want to be able to show the image...
$this->set('image', $this->Image->findById($id);
// But we also want links to the previous and next images...
$this->set(
'neighbors',
$this->Image->findNeighbours(null, 'id', $id);
)
}
}
class ImagesController extends AppController {function view($id) {// Say we want to be able to show the image...$this->set('image', $this->Image->findById($id);// But we also want links to the previous and next images...$this->set('neighbors',$this->Image->findNeighbours(null, 'id', $id);)}}
This gives us the full $image['Image'] array, along with $neighbors['prev']['Image']['id'] and $neighbors['next']['Image']['id'] for use in the view.
Returns the value of a single field, specified as $name, from the first record matched by $conditions as ordered by $order.
Returns the number of records that match the given conditions. Use the $recursive parameter to have CakePHP fetch more (or fewer) levels of associated models.
This function is a shortcut to getting a list of key value pairs - especially handy for creating an HTML select tag from a list of your models. Use the $conditions, $order, and $limit parameters just as you would for a findAll() request.
If $primaryKey and $displayField have been set in the model, you don’t need to supply the last two parameters, as they act as $keyPath and $keyValue, respectively. Additionally, if neither $keyPath or $displayField have been supplied, CakePHP will try to load the information using ‘title’ or ‘name’.
The $keyPath and $valuePath specify where to find the keys and values for your generated list. For example, if you wanted to generate a list of roles based on your Role model, keyed by their integer ids, the full call might look something like:
$this->Role->generateList(
null,
'role_name ASC',
null,
'{n}.Role.id',
'{n}.Role.role_name'
);
//This would return something like:
array(
'1' => 'Head Honcho',
'2' => 'Marketing',
'3' => 'Department Head',
'4' => 'Grunt'
);
$this->Role->generateList(null,'role_name ASC',null,'{n}.Role.id','{n}.Role.role_name');//This would return something like:array('1' => 'Head Honcho','2' => 'Marketing','3' => 'Department Head','4' => 'Grunt');
Many people are a little bewildered by the ‘{n}’ syntax used by generateList(). Fret not, for it serves as a place holder for switching between model DataSources, covered later on in this chapter.
Custom SQL calls can be made using the model's query() and execute() methods. The difference between the two is that query() is used to make custom SQL queries (the results of which are returned), and execute() is used to make custom SQL commands (which supply no return value).
If you’re ever using custom SQL queries in your application, be sure to check out CakePHP’s Sanitize library (covered later in this manual), which aids in cleaning up user-provided data from injection and cross-site scripting attacks.
findAll
findAll(string $conditions, array $fields, string $order, int $limit, int $page, int $recursive);
findAll(string $conditions, array $fields, string $order, int $limit, int $page, int $recursive);
Returns the specified fields up to $limit records matching $conditions (if any), start listing from page $page (default is page 1). If there are no matching fields, an empty array is returned.
The $conditions should be formed just as they would in an SQL statement: $conditions = "Pastry.type LIKE '%cake%' AND Pastry.created_on > ‘2007-01-01’", for example. Prefixing conditions with the model’s name (‘Pastry.type’ rather than just ‘type’) is always a good practice, especially when associated data is being fetched in a query.
Setting the $recursive parameter to an integer forces findAll() to fetch data according to the behavior described in the Model Attributes $recursive section outlined earlier.
Data from findAll() is returned in an array, following this basic format:
Array
(
[0] => Array
(
[ModelName] => Array
(
[id] => 83
[field1] => value1
[field2] => value2
[field3] => value3
)
[AssociatedModelName] => Array
(
[id] => 1
[field1] => value1
[field2] => value2
[field3] => value3
)
)
[1] => Array
(
[ModelName] => Array
(
[id] => 85
[field1] => value1
[field2] => value2
[field3] => value3
)
[AssociatedModelName] => Array
(
[id] => 2
[field1] => value1
[field2] => value2
[field3] => value3
)
)
)
Array([0] => Array([ModelName] => Array([id] => 83[field1] => value1[field2] => value2[field3] => value3)[AssociatedModelName] => Array([id] => 1[field1] => value1[field2] => value2[field3] => value3))[1] => Array([ModelName] => Array([id] => 85[field1] => value1[field2] => value2[field3] => value3)[AssociatedModelName] => Array([id] => 2[field1] => value1[field2] => value2[field3] => value3)))
find
find(string $conditions, array $fields, string $order, int $recursive);
find(string $conditions, array $fields, string $order, int $recursive);
Same as in findAll(), except that find only returns the first record matching the supplied $conditions.
The find methods were recently consolidated and find() can now be used to fulfil all of your find-ing needs. There is a slightly different syntax to the calls:
find($type, $params);
find($type, $params);
$type is either 'all', 'list' or 'first'. First is the default find type.
$params is an array with any of the following available options as keys:
array(
'conditions' => array('Model.field' => $thisValue), //array of conditions
'recursive' => 1, //int
'fields' => array('Model.field1', 'Model.field2'), //array of field names
'order' => 'Model.created', //string or array defining order
'limit' => n, //int
'page' => n //int
) array('conditions' => array('Model.field' => $thisValue), //array of conditions'recursive' => 1, //int'fields' => array('Model.field1', 'Model.field2'), //array of field names'order' => 'Model.created', //string or array defining order'limit' => n, //int'page' => n //int)
If you are using find('list'), the 'fields' key in $params defines the key, value and group
// generated list will be indexed by Post.id, with value of Post.title
$this->Post->find('list', array('fields'=>'Post.title'));
// generated list will be indexed by Post.slug, with value of Post.title
$this->Post->find('list', array('fields'=>array('Post.slug', 'Post.title')));
// generated list will be grouped by Post.author_id, and each group indexed by Post.id, with value of Post.title
$this->Post->find('list', array('fields'=>array('Post.id', 'Post.title', 'Post.author_id')));
// generated list will be indexed by Post.id, with value of Post.title$this->Post->find('list', array('fields'=>'Post.title'));// generated list will be indexed by Post.slug, with value of Post.title$this->Post->find('list', array('fields'=>array('Post.slug', 'Post.title')));// generated list will be grouped by Post.author_id, and each group indexed by Post.id, with value of Post.title$this->Post->find('list', array('fields'=>array('Post.id', 'Post.title', 'Post.author_id')));
findAllBy
findAllBy<fieldName>(string $value)
findAllBy<fieldName>(string $value)
These magic functions can be used as a shortcut to search your tables by a certain field. Just add the name of the field (in CamelCase format) to the end of these functions, and supply the criteria for that field as the first parameter.
findBy
findBy<fieldName>(string $value);
findBy<fieldName>(string $value);
These magic functions can be used as a shortcut to search your tables by a certain field. Just add the name of the field (in CamelCase format) to the end of these functions, and supply the criteria for that field as the first parameter.
| PHP5 findAllBy<x> Example | Corresponding SQL Fragment |
|---|---|
| $this->Product->findAllByOrderStatus(‘3’); | Product.order_status = 3 |
| $this->Recipe->findAllByType(‘Cookie’); | Recipe.type = ‘Cookie’ |
| $this->User->findAllByLastName(‘Anderson’); | User.last_name = ‘Anderson’ |
| $this->Cake->findById(7); | Cake.id = 7 |
| $this->User->findByUserName(‘psychic’); | User.user_name = ‘psychic’ |
PHP4 users have to use this function a little differently due to some case-insensitivity in PHP4:
| PHP4 findAllBy<x> Example | Corresponding SQL Fragment |
|---|---|
| $this->Product->findAllByOrder_status(‘3’); | Product.order_status = 3 |
| $this->Recipe->findAllByType(‘Cookie’); | Recipe.type = ‘Cookie’ |
| $this->User->findAllByLast_name(‘Anderson’); | User.last_name = ‘Anderson’ |
| $this->Cake->findById(7); | Cake.id = 7 |
| $this->User->findByUser_name(‘psychic’); | User.user_name = ‘psychic’ |
The returned result is an array formatted just as it would be from find() or findAll().
findNeighbours
This shortcut method creates an array containing values helpful in generating 'Previous' and 'Next' links in a view.
The method determines which data rows to return based on the values submitted in the $field and $value parameters. Further refinement can be done with the $conditions parameter.
For example, if you call the function like this:
$conditions = array('Article.status' => 'published');
$field = array('date', 'id');
$value = '2008-03-24';
$this->Article->findNeighbours( $conditions, $field, $value ) );
$conditions = array('Article.status' => 'published');$field = array('date', 'id');$value = '2008-03-24';$this->Article->findNeighbours( $conditions, $field, $value ) );
The resulting array will contain values for the 'date' and 'id' fields from the articles who have a status of "published", and whose dates are just before and after the date '2008-03-24'.
// note that the comparison was made on date field, and that
// the id values were not used to determine neighboring data
Array
(
[prev] => Array ([Article] =>
Array ([date] => 2008-03-20, [id] => 99 )
),
[next] => Array ( [Article] =>
array( [date] => 2008-03-27, [id] => 15 )
)
);
// note that the comparison was made on date field, and that// the id values were not used to determine neighboring dataArray([prev] => Array ([Article] =>Array ([date] => 2008-03-20, [id] => 99 )),[next] => Array ( [Article] =>array( [date] => 2008-03-27, [id] => 15 )));
This method can also be called with the $field value being a single string. When an array is used, the first field listed will be the field used in the comparison query.
class ImagesController extends AppController {
function view($id) {
// Say we want to be able to show the image...
$this->set('image', $this->Image->findById($id);
// But we also want links to the previous and next images...
$this->set(
'neighbors',
$this->Image->findNeighbours(null, 'id', $id);
)
}
}
class ImagesController extends AppController {function view($id) {// Say we want to be able to show the image...$this->set('image', $this->Image->findById($id);// But we also want links to the previous and next images...$this->set('neighbors',$this->Image->findNeighbours(null, 'id', $id);)}}
This gives us the full $image['Image'] array, along with $neighbors['prev']['Image']['id'] and $neighbors['next']['Image']['id'] for use in the view.
field
field(string $name, string $conditions, string $order)
field(string $name, string $conditions, string $order)
Returns the value of a single field, specified as $name, from the first record matched by $conditions as ordered by $order.
findCount
findCount(string $conditions, int $recursive)
findCount(string $conditions, int $recursive)
Returns the number of records that match the given conditions. Use the $recursive parameter to have CakePHP fetch more (or fewer) levels of associated models.
generateList
generateList(string $conditions, string $order, int $limit, string $keyPath, string $valuePath)
generateList(string $conditions, string $order, int $limit, string $keyPath, string $valuePath)
This is deprecated and will be replaced by usage of find('list') on it's own or find('all') combined with a call to Set::combine().
This function is a shortcut to getting a list of key/value pairs - especially handy for creating an HTML select tag from a list of your models. Use the $conditions, $order, and $limit parameters just as you would for a findAll() request.
If $primaryKey and $displayField have been set in the model, you don’t need to supply the last two parameters, as they act as $keyPath and $keyValue, respectively. Additionally, if neither $keyPath nor $displayField have been supplied, CakePHP will try to load the information using ‘title’ or ‘name’.
The $keyPath and $valuePath specify where to find the keys and values for your generated list. For example, if you wanted to generate a list of roles based on your Role model, keyed by their integer ids, the full call might look something like:
$this->Role->generateList(
null,
'role_name ASC',
null,
'{n}.Role.id',
'{n}.Role.role_name'
);
//This would return something like:
array(
'1' => 'Head Honcho',
'2' => 'Marketing',
'3' => 'Department Head',
'4' => 'Grunt'
);
$this->Role->generateList(null,'role_name ASC',null,'{n}.Role.id','{n}.Role.role_name');//This would return something like:array('1' => 'Head Honcho','2' => 'Marketing','3' => 'Department Head','4' => 'Grunt');
Many people are a little bewildered by the ‘{n}’ syntax used by generateList(). Fret not, for it serves as a place holder for switching between model DataSources, covered later on in this chapter.
query and execute
query(string $query), execute(string $query)
query(string $query), execute(string $query)
Custom SQL calls can be made using the model's query() and execute() methods. The difference between the two is that query() is used to make custom SQL queries (the results of which are returned), and execute() is used to make custom SQL commands (which supply no return value).
If you’re ever using custom SQL queries in your application, be sure to check out CakePHP’s Sanitize library (covered later in this manual), which aids in cleaning up user-provided data from injection and cross-site scripting attacks.
Conditions de recherche complexes
Most of the model's find calls involve passing sets of conditions in one way or another. The simplest approach to this is to use a WHERE clause snippet of SQL. If you find yourself needing more control, you can use arrays.
Using arrays is clearer and easier to read, and also makes it very easy to build queries. This syntax also breaks out the elements of your query (fields, values, operators, etc.) into discreet, manipulatable parts. This allows CakePHP to generate the most efficient query possible, ensure proper SQL syntax, and properly escape each individual part of the query.
At it's most basic, an array-based query looks like this:
$conditions = array("Post.title" => "This is a post");
//Example usage with a model:
$this->Post->find($conditions);
$conditions = array("Post.title" => "This is a post");//Example usage with a model:$this->Post->find($conditions);
The structure here is fairly self-explanatory: it will find any post where the title equals "This is a post". Note that we could have used just "title" as the field name, but when building queries, it is good practice to always specify the model name, as it improves the clarity of the code, and helps prevent collisions in the future, should you choose to change your schema.
What about other types of matches? These are equally simple. Let's say we wanted to find all the posts where the title is not "This is a post":
array("Post.title" => "<> This is a post")
array("Post.title" => "<> This is a post")
Notice the '<>' that prefixes the expression. CakePHP can parse out any valid SQL comparison operator, including match expressions using LIKE, BETWEEN, or REGEX, as long as you leave a space between the operator and the value. The one exception here is IN (...)-style matches. Let's say you wanted to find posts where the title was in a given set of values:
array(
"Post.title" => array("First post", "Second post", "Third post")
)
array("Post.title" => array("First post", "Second post", "Third post"))
Adding additional filters to the conditions is as simple as adding additional key/value pairs to the array:
array
(
"Post.title" => array("First post", "Second post", "Third post"),
"Post.created" => "> " . date('Y-m-d', strtotime("-2 weeks"))
)
array("Post.title" => array("First post", "Second post", "Third post"),"Post.created" => "> " . date('Y-m-d', strtotime("-2 weeks")))
By default, CakePHP joins multiple conditions with boolean AND; which means, the snippet above would only match posts that have been created in the past two weeks, and have a title that matches one in the given set. However, we could just as easily find posts that match either condition:
array
("or" =>
array
(
"Post.title" =>
array("First post", "Second post", "Third post"),
"Post.created" => "> " . date('Y-m-d', strtotime("-2 weeks"))
)
)
array("or" =>array("Post.title" =>array("First post", "Second post", "Third post"),"Post.created" => "> " . date('Y-m-d', strtotime("-2 weeks"))))
Cake accepts all valid SQL boolean operations, including AND, OR, NOT, XOR, etc., and th
login to add a comment