cvs: peardoc /en/package/database/db-dataobject intro-purpose.xml
| From: | Alan Knowles | Date: | Tue, 29 Apr 2003 05:26:56 +0000 |
| Subject: | cvs: peardoc /en/package/database/db-dataobject intro-purpose.xml | ||
| Groups: | php.pear.doc | ||
| Request: | Send a blank email to pear-doc+get-691@lists.php.net to get a copy of this message | ||
alan_k Tue Apr 29 01:26:56 2003 EDT
Modified files:
/peardoc/en/package/database/db-dataobject intro-purpose.xml
Log:
a bigger - and hopefully clearer introduction
Index: peardoc/en/package/database/db-dataobject/intro-purpose.xml diff -u peardoc/en/package/database/db-dataobject/intro-purpose.xml:1.2 peardoc/en/package/database/db-dataobject/intro-purpose.xml:1.3 --- peardoc/en/package/database/db-dataobject/intro-purpose.xml:1.2 Mon Mar 10 17:27:41 2003 +++ peardoc/en/package/database/db-dataobject/intro-purpose.xml Tue Apr 29 01:26:56 2003 @@ -1,9 +1,9 @@ -<!-- $Revision: 1.2 $ --> +<!-- $Revision: 1.3 $ --> <refentry id="package.database.db-dataobject.intro-purpose"> <refnamediv> <refname>Introduction</refname> <refpurpose> - What DB_DataObject can do + What <classname>DB_DataObject</classname> can do </refpurpose> </refnamediv> <refsect1> @@ -25,44 +25,289 @@ </listitem> </itemizedlist> </para> + + <para> + So what does that mean in english?, well, if you look around at some of the better written PHP + applications and frameworks out there, you will notice a common approach to using classes to + wrap access to database tables or groups. The prime example of this is the person object, which would + frequently look something like this. + + <example> + <title>A Classic Data Object or Container</title> + <programlisting role="php"> + <![CDATA[ + + class MyPerson { + + // gets an array of data about the seleted person + function getPerson($id) { + global $db; + $result = $db->query("SELECT * FROM person WHERE id=$id"); + return $result->fetchRow(); + } + + // example of checking a password. + function checkPassword($username,$password) { + global $db; + $db->query("SELECT username FROM person WHERE username='$username' AND password = '$pasword'"); + return $result->fetchRow(); + } + + } + + // get the persons details.. + $array = MyPerson::getPerson(12); + + + ]]> + </programlisting></example> + </para> <para> - The <classname>DB_DataObject</classname> is rarely accessed directly, - it is intended to be the base class which you can - extend to put the code specifically relating to a particular database table. Below is an example of how you - can use the end result (and extended class), + The key benifit of this approach is that you grouping similar actions on a single table in one place, and are + more likely to spot duplicated code (eg. two methods that do similar things). You will also notice the global $db variable + used here - the fact is that most of the time you will use a common database connection for all your classes, so how should this + be dealt with? </para> + <para> + The next step on this road is to use the objects variables as a storage mechanism. + <example> - <title>Typical usage example for <classname>PEAR::DB_DataObject</classname></title> + <title>A Classic Data Object or Container</title> + <programlisting role="php"> + <![CDATA[ + + class MyPerson { + + var $id; + var $name; + var $birthDate; + + + // gets an array of data about the seleted person + function get($id) { + global $db; + $result = $db->query("SELECT * FROM person WHERE id=$id"); + $array = $result->fetchRow(); + foreach($array as $key=>$value) { + $this->$key = $value; + } + } + + function getAge() { + $age = data('Y') - date('Y',$birthDate); + } + + } + // now get the person and display the age. + $person = new MyPerson; + $person->get(12); + echo "{$person->name} is ". $person->getAge() . " years old"; + + + ]]> + </programlisting></example> + </para> + <para> + As you can see, the current row of data is now stored in the Data Container, and additional methods can be added to manipulate + the data in the object or even call other related objects (eg. tables relationships in databases) + </para> + + <para> + As a next step, why not utilize the member variables to perform searches or gets on the database. + + + + + <example> + <title>A Classic Data Object or Container</title> <programlisting role="php"> <![CDATA[ - // initialize the DataObject Manager + class MyPerson { + + var $id; + var $name; + var $birthDate; + + + // does the query based on the value of $this->name + function find() { + global $db; + $this->result = $db->query("SELECT * FROM person WHERE name={$this->name)"); + } + + // fetches a row of data and sets the object variables to match it. + + function fetch() { + $array = $this->result->fetchRow(); + if (empty($array)) { + return false; + } + foreach($array as $key=>$value) { + $this->$key = $value; + } + } + + } + // now get the person and display the age. + $person ->name = "John"; + $person->find(); + while ($person->fetch()) { + echo "a {$person->name} has a birthday on {$person->birthDate}\n"; + } + + + ]]> + </programlisting></example> + </para> + <para> + As you can see, by assigning values to the object before the find method is called, you can set conditions for the query. + <classname>DB_DataObject</classname>s behaves in a similar way to this, however, you can also add more conditions with the whereAdd() method, or + restrict the selection using the selectAdd() Method. + </para> + + + <para> + Obviously you can carry on down this road and create lots of little containers for each table in your database, + and all the code will nicely relate to each table. However, you can see from the examples above that all classes + are likely to end up with a common set of methods. + <itemizedlist> + <listitem> + <simpara> to fetch data, like get, find, fetch</simpara> + </listitem> + <listitem> + <simpara> to update, insert and delete from the data store</simpara> + </listitem> + <listitem> + <simpara> to automate fetching related objects</simpara> + </listitem> + </itemizedlist> + So to improve on this, <classname>DB_DataObject</classname> was born, it started life as an common answer to the issues above, however as most + problems grow in complexity as the problem is examined in finer detail, so has DataObjects. It has grown to include + <itemizedlist> + <listitem> + <simpara> A common simple configuration method (for setting database connections)</simpara> + </listitem> + <listitem> + <simpara> A fast and simple store for database descriptions, so primary keys can be used to locate data quickly</simpara> + </listitem> + <listitem> + <simpara> a debugger that enables you to see what exactly it is doing.</simpara> + </listitem> + <listitem> + <simpara> basic data validation - so the strings and integers can be checked.</simpara> + </listitem> + <listitem> + <simpara> Posibility to build complex joins or get related data by secondary calls (links) .</simpara> + </listitem> + <listitem> + <simpara> Ability to create and update your Table specific classes with the current database table variables (see autobuilding)</simpara> + </listitem> + <listitem> + <simpara> Simple to integrate with other packages, with setFrom() and toArray() methods</simpara> + </listitem> + </itemizedlist> + + + </para> + + + <para> + So what do my classes look like? + <example> + <title>At last some real DataObject Code..</title> + <programlisting role="php"> + <![CDATA[ + + + // this is the common configuration code - place in a general site wide include file. + + // this the code used to load and store DataObjects Configuration. + $options = &PEAR::getStaticProperty('DB_DataObject','options'); + + // the simple examples use parse_ini_file, which is fast and efficient. + // however you could as easily use wddx, xml or your own configuration array. + $config = parse_ini_file('example.ini',TRUE); + + // because PEAR::getstaticProperty was called with and & (get by reference) + // this will actually set the variable inside that method (a quasi static variable) + $options = $config['DB_DataObject']; - require_once('PEAR.php'); - $options = &PEAR::getStaticProperty('DB_DataObject','options'); - $config = parse_ini_file('example.ini',TRUE); - $options = $config['DB_DataObject']; - // use one of the extended classes. - require_once('DataObjects/Person.php'); - $person = new DataObjects_Person; - $person->get(12); - echo $person->name; + // this is normally contained in your DataObjects file (autogenerated by the generator) + require_once 'DB/DataObject.php'; + + + // by extending the base class DB_DataObject - you inherit all the common methods defined in it. + + class DataObjects_Person extends DB_DataObject { + + var $id; // this is a primary id (it's specified in a config file - explained later) + var $name; + var $friend; + + // this is a simple function to get the persons friends..? + + function getFriends() + { + + $personObject = new DataObjects_Person; + + // look for all people with their friend number matching this persons id. + $personObject->friend = $this->id; + + // do the select query. + $personObject->find(); + $array = array(); + + // fetch the results into the object. + while ($personObject->fetch()) { + // use the clone to copy - not really needed but get used to it for PHP5 + $array[] = $personObject->__clone(); + } + // return the results. + return $array; + + } + } + + + + // and this goes on your display code + + // create a new person class.. + $person = new DataObjects_Person; + + // get the person using the primary key. + $person->get(12); + // get the friends. + $friends = $person->getFriends(); + + // DB_DataObjects is designed to make print_r useable to debug your applications. + print_r($friends); ]]> - </programlisting> - </example> + </programlisting></example> + + </para> + + + <para> - The above example illustrates the two components of the - <command>DataManager</command>, by setting the options, all + The above example illustrates the components of the + <classname>DB_DataObject</classname>, by setting the options, all the core objects will be able to auto load the data definitions from a generated ini file, and know how to access the database. (multiple databases are supported - see section on configuration) </para> <para> + The class definition illustrates how you only need to define the data specific code in your class, ignoring + all the common methods, along with showing one of the methods for retrieveing multiple rows of data. + </para> + <para> The later half illustrates how to query and get the result for a single row. The <link linkend="package.db.db-dataobject.db-dataobject.get"><function>$person->get</function></link> would connect to the database, perform the query, fetch the result and assign the objects variables to the data returned @@ -73,8 +318,9 @@ In the above example, this query would be performed. </para> - <programlisting role="php"> + <programlisting role="sql"> SELECT * FROM person WHERE id=12; + SELECT * FROM person WHERE friend=12; </programlisting> <para> @@ -82,7 +328,7 @@ the update method. </para> - <programlisting role="php"> + <programlisting role="sql"> <![CDATA[ @@ -95,38 +341,13 @@ ]]> </programlisting> - - <para> - The Package includes a number of tools to make building the extended - classes and configuration file; - once you have made your extended classes, the idea is that any data manipulation/calculation that relates - to this table, or how this table interacts with other data is placed inside the extended class. + + <para> + As a general rule of thumb method names are usually the same as the SQL statement they relate to. </para> - <programlisting role="php"> - <![CDATA[ - - require_once 'DB/DataObject.php'; - - class DataObjects_Person extends DB_DataObject { - - function &listMembership() - { - $members = new DataObjects_Members(); - $members->person_id = $this->id; - $members->find(); - return $members; - } - } - - - ]]> - </programlisting> - <para> - In this example the <classname>Person</classname> - object asks the <classname>Members</classname> Object to list all records that have the column - person_id equal to the current instance's id. - </para> + + </refsect1> </refentry> <!-- Keep this comment at the end of the file
Index: peardoc/en/package/database/db-dataobject/intro-purpose.xml diff -u peardoc/en/package/database/db-dataobject/intro-purpose.xml:1.2 peardoc/en/package/database/db-dataobject/intro-purpose.xml:1.3 --- peardoc/en/package/database/db-dataobject/intro-purpose.xml:1.2 Mon Mar 10 17:27:41 2003 +++ peardoc/en/package/database/db-dataobject/intro-purpose.xml Tue Apr 29 01:26:56 2003 @@ -1,9 +1,9 @@ -<!-- $Revision: 1.2 $ --> +<!-- $Revision: 1.3 $ --> <refentry id="package.database.db-dataobject.intro-purpose"> <refnamediv> <refname>Introduction</refname> <refpurpose> - What DB_DataObject can do + What <classname>DB_DataObject</classname> can do </refpurpose> </refnamediv> <refsect1> @@ -25,44 +25,289 @@ </listitem> </itemizedlist> </para> + + <para> + So what does that mean in english?, well, if you look around at some of the better written PHP + applications and frameworks out there, you will notice a common approach to using classes to + wrap access to database tables or groups. The prime example of this is the person object, which would + frequently look something like this. + + <example> + <title>A Classic Data Object or Container</title> + <programlisting role="php"> + <![CDATA[ + + class MyPerson { + + // gets an array of data about the seleted person + function getPerson($id) { + global $db; + $result = $db->query("SELECT * FROM person WHERE id=$id"); + return $result->fetchRow(); + } + + // example of checking a password. + function checkPassword($username,$password) { + global $db; + $db->query("SELECT username FROM person WHERE username='$username' AND password = '$pasword'"); + return $result->fetchRow(); + } + + } + + // get the persons details.. + $array = MyPerson::getPerson(12); + + + ]]> + </programlisting></example> + </para> <para> - The <classname>DB_DataObject</classname> is rarely accessed directly, - it is intended to be the base class which you can - extend to put the code specifically relating to a particular database table. Below is an example of how you - can use the end result (and extended class), + The key benifit of this approach is that you grouping similar actions on a single table in one place, and are + more likely to spot duplicated code (eg. two methods that do similar things). You will also notice the global $db variable + used here - the fact is that most of the time you will use a common database connection for all your classes, so how should this + be dealt with? </para> + <para> + The next step on this road is to use the objects variables as a storage mechanism. + <example> - <title>Typical usage example for <classname>PEAR::DB_DataObject</classname></title> + <title>A Classic Data Object or Container</title> + <programlisting role="php"> + <![CDATA[ + + class MyPerson { + + var $id; + var $name; + var $birthDate; + + + // gets an array of data about the seleted person + function get($id) { + global $db; + $result = $db->query("SELECT * FROM person WHERE id=$id"); + $array = $result->fetchRow(); + foreach($array as $key=>$value) { + $this->$key = $value; + } + } + + function getAge() { + $age = data('Y') - date('Y',$birthDate); + } + + } + // now get the person and display the age. + $person = new MyPerson; + $person->get(12); + echo "{$person->name} is ". $person->getAge() . " years old"; + + + ]]> + </programlisting></example> + </para> + <para> + As you can see, the current row of data is now stored in the Data Container, and additional methods can be added to manipulate + the data in the object or even call other related objects (eg. tables relationships in databases) + </para> + + <para> + As a next step, why not utilize the member variables to perform searches or gets on the database. + + + + + <example> + <title>A Classic Data Object or Container</title> <programlisting role="php"> <![CDATA[ - // initialize the DataObject Manager + class MyPerson { + + var $id; + var $name; + var $birthDate; + + + // does the query based on the value of $this->name + function find() { + global $db; + $this->result = $db->query("SELECT * FROM person WHERE name={$this->name)"); + } + + // fetches a row of data and sets the object variables to match it. + + function fetch() { + $array = $this->result->fetchRow(); + if (empty($array)) { + return false; + } + foreach($array as $key=>$value) { + $this->$key = $value; + } + } + + } + // now get the person and display the age. + $person ->name = "John"; + $person->find(); + while ($person->fetch()) { + echo "a {$person->name} has a birthday on {$person->birthDate}\n"; + } + + + ]]> + </programlisting></example> + </para> + <para> + As you can see, by assigning values to the object before the find method is called, you can set conditions for the query. + <classname>DB_DataObject</classname>s behaves in a similar way to this, however, you can also add more conditions with the whereAdd() method, or + restrict the selection using the selectAdd() Method. + </para> + + + <para> + Obviously you can carry on down this road and create lots of little containers for each table in your database, + and all the code will nicely relate to each table. However, you can see from the examples above that all classes + are likely to end up with a common set of methods. + <itemizedlist> + <listitem> + <simpara> to fetch data, like get, find, fetch</simpara> + </listitem> + <listitem> + <simpara> to update, insert and delete from the data store</simpara> + </listitem> + <listitem> + <simpara> to automate fetching related objects</simpara> + </listitem> + </itemizedlist> + So to improve on this, <classname>DB_DataObject</classname> was born, it started life as an common answer to the issues above, however as most + problems grow in complexity as the problem is examined in finer detail, so has DataObjects. It has grown to include + <itemizedlist> + <listitem> + <simpara> A common simple configuration method (for setting database connections)</simpara> + </listitem> + <listitem> + <simpara> A fast and simple store for database descriptions, so primary keys can be used to locate data quickly</simpara> + </listitem> + <listitem> + <simpara> a debugger that enables you to see what exactly it is doing.</simpara> + </listitem> + <listitem> + <simpara> basic data validation - so the strings and integers can be checked.</simpara> + </listitem> + <listitem> + <simpara> Posibility to build complex joins or get related data by secondary calls (links) .</simpara> + </listitem> + <listitem> + <simpara> Ability to create and update your Table specific classes with the current database table variables (see autobuilding)</simpara> + </listitem> + <listitem> + <simpara> Simple to integrate with other packages, with setFrom() and toArray() methods</simpara> + </listitem> + </itemizedlist> + + + </para> + + + <para> + So what do my classes look like? + <example> + <title>At last some real DataObject Code..</title> + <programlisting role="php"> + <![CDATA[ + + + // this is the common configuration code - place in a general site wide include file. + + // this the code used to load and store DataObjects Configuration. + $options = &PEAR::getStaticProperty('DB_DataObject','options'); + + // the simple examples use parse_ini_file, which is fast and efficient. + // however you could as easily use wddx, xml or your own configuration array. + $config = parse_ini_file('example.ini',TRUE); + + // because PEAR::getstaticProperty was called with and & (get by reference) + // this will actually set the variable inside that method (a quasi static variable) + $options = $config['DB_DataObject']; - require_once('PEAR.php'); - $options = &PEAR::getStaticProperty('DB_DataObject','options'); - $config = parse_ini_file('example.ini',TRUE); - $options = $config['DB_DataObject']; - // use one of the extended classes. - require_once('DataObjects/Person.php'); - $person = new DataObjects_Person; - $person->get(12); - echo $person->name; + // this is normally contained in your DataObjects file (autogenerated by the generator) + require_once 'DB/DataObject.php'; + + + // by extending the base class DB_DataObject - you inherit all the common methods defined in it. + + class DataObjects_Person extends DB_DataObject { + + var $id; // this is a primary id (it's specified in a config file - explained later) + var $name; + var $friend; + + // this is a simple function to get the persons friends..? + + function getFriends() + { + + $personObject = new DataObjects_Person; + + // look for all people with their friend number matching this persons id. + $personObject->friend = $this->id; + + // do the select query. + $personObject->find(); + $array = array(); + + // fetch the results into the object. + while ($personObject->fetch()) { + // use the clone to copy - not really needed but get used to it for PHP5 + $array[] = $personObject->__clone(); + } + // return the results. + return $array; + + } + } + + + + // and this goes on your display code + + // create a new person class.. + $person = new DataObjects_Person; + + // get the person using the primary key. + $person->get(12); + // get the friends. + $friends = $person->getFriends(); + + // DB_DataObjects is designed to make print_r useable to debug your applications. + print_r($friends); ]]> - </programlisting> - </example> + </programlisting></example> + + </para> + + + <para> - The above example illustrates the two components of the - <command>DataManager</command>, by setting the options, all + The above example illustrates the components of the + <classname>DB_DataObject</classname>, by setting the options, all the core objects will be able to auto load the data definitions from a generated ini file, and know how to access the database. (multiple databases are supported - see section on configuration) </para> <para> + The class definition illustrates how you only need to define the data specific code in your class, ignoring + all the common methods, along with showing one of the methods for retrieveing multiple rows of data. + </para> + <para> The later half illustrates how to query and get the result for a single row. The <link linkend="package.db.db-dataobject.db-dataobject.get"><function>$person->get</function></link> would connect to the database, perform the query, fetch the result and assign the objects variables to the data returned @@ -73,8 +318,9 @@ In the above example, this query would be performed. </para> - <programlisting role="php"> + <programlisting role="sql"> SELECT * FROM person WHERE id=12; + SELECT * FROM person WHERE friend=12; </programlisting> <para> @@ -82,7 +328,7 @@ the update method. </para> - <programlisting role="php"> + <programlisting role="sql"> <![CDATA[ @@ -95,38 +341,13 @@ ]]> </programlisting> - - <para> - The Package includes a number of tools to make building the extended - classes and configuration file; - once you have made your extended classes, the idea is that any data manipulation/calculation that relates - to this table, or how this table interacts with other data is placed inside the extended class. + + <para> + As a general rule of thumb method names are usually the same as the SQL statement they relate to. </para> - <programlisting role="php"> - <![CDATA[ - - require_once 'DB/DataObject.php'; - - class DataObjects_Person extends DB_DataObject { - - function &listMembership() - { - $members = new DataObjects_Members(); - $members->person_id = $this->id; - $members->find(); - return $members; - } - } - - - ]]> - </programlisting> - <para> - In this example the <classname>Person</classname> - object asks the <classname>Members</classname> Object to list all records that have the column - person_id equal to the current instance's id. - </para> + + </refsect1> </refentry> <!-- Keep this comment at the end of the file