Pear_dataobject

Pear_dataobject

Introduction

Ceci est mon premier tutorial donc ...

DataObject est une couche d'abstraction de base de données gérant les tables comme une classe object... Elle permet de se connecter à n'importe quelle base de données en gardant les mêmes fonctions ; donc inutile de changer le code (Mysql, PostGrepSql, Oracle, ODBC, ...). De plus, chaque table de la base de données est représentée par un classe object héritée de DataObject ...

Tout d'abord, voici la structure du serveur web que j'utilise. Tout les références seront basées sur cette structure ...

/usr -> composant du serveur
/usr/local/Apache2 -> le serveur Apache
/usr/local/Mysql -> Base de Données ... Les exemples donnés seront pour cette base de données...
/usr/local/PHP -> Composant pour PHP
/usr/local/PHP/PEAR -> Répertoire dédié pour PEAR et ses classes ...
/www/ --> répertoire ou seront placés les fichiers web ....

Pour l'exemple :
/www/AssetManagement --> mon répertoire de travail. Il vous faudra définir un répertoire pour la création des classes par DataObject (précisé plus bas)
/www/AssetMagement/classes -> contient toutes les classes
/www/AssetMagement/ini --> contient les fichiers ini

Telechargements

PEAR_DB
et
PEAR_DataObject

Pour ceux utilisant PHP sous Windows (EasyPHP, Uniserver), la plupart des packages sont déjà installés, il faut parfois juste dé-commenter certaines lignes de PHP.ini ...

Tout d'abord, il faut éditer le fichier PHP.ini :
safe_mode_include_dir = ".;/usr/local/PHP/includes;/usr/local/PHP/pear;/usr/local/PHP/pear/Db"
include_path = ".;/usr/local/PHP/includes;/usr/local/PHP/pear;/usr/local/PHP/pear/Db"

Ces lignes permettent juste de préciser le chemin de recherche des packages pour PEAR.

Ensuite, une fois téléchargés les packets pour DataObject du lien ci-dessus, vous décompressez PEAR DB et vous le copiez dans/usr/local/PHP/PEAR/DB et
PEAR_DataObject dans .../PEAR/DB/DataObject. Tous les packages utilisant DataObject (et ils sont nombreux) devront se placer dans ce répertoire ..

Donc ...

Nouvelle structure du site :
/usr/local/PHP/PEAR/DB -> repertoire contenant tout les packages de couche d'abstraction
/usr/local/PHP/PEAR/DB/DataObject -> repertoire contenant le package DataObject et ses derives (quick_form, ...)

Maintenant la partie configuration ... (celle ou je me suis le plus battue pour la faire fonctionner ...)

Configuration

Dans ../DataObject, il devrait y avoir 2 fichiers :
DataObject.ini et DOconfig.ini ... S'ils n'y sont pas, il faudra les créer ..

DataObject.ini

; DataObject INI File
[DB]
[DB_DataObject]
database = mysql://usert:somepassword@localhost/db
; the default database dsn see pear spec for more details
schema_location = /www/AssetManagement/ini
class_location = /www//AssetManagement/classes
require_prefix = DataObjects/
class_prefix = DataObjects_
debug = 0
debug_ignore_updates = 0
dont_die = 0
dont_use_pear_sequences = 0
build_views = 0
----------------------------

- database <--- type de la base de données et paramètres y afférant ...
- schema_location <--- emplacement pour les fichiers de configuration de la base de données...
- class_location <-- Emplacement des classes d'objects ... sera l'emplacement par défaut lors de l'auto-création des classes....

DOConfig

<?
require_once('PEAR.php');
$config = parse_ini_file('DataObject.ini',TRUE);
      foreach($config as $class=>$values) {
          $options = &PEAR::getStaticProperty($class,'options');
          $options = $values;
      }
$_DB_DATAOBJECT_FORMBUILDER['CONFIG'] = $config['DB_DataObject_FormBuilder'];
?>

DOConfig contient les définitions et le code nécessaire pour le fonctionnement des classes et package de DataObject. Ci-dessus, il y a également le module FormBuilder. Pour celui-ci on ajoutera une section supplémentaire dans DataObject.ini ... (Hors tuto donc je passe )...

Le contenu du repertoire ini (ma base de données s'appelle "asset"):

ini <-- auto-créé lors de la génération des classes==

exemple :
[department]
ID_Dept = 129
DIERCODE = 2
Department = 2

[department__keys]
ID_Dept = N

[employee]
ID_Employee = 129
ID_Title = 1
ID_Function = 1
ID_Dept = 1
ID_StatEmp = 1
LastName = 2
FirstName = 2
Login = 2
PhoneExt = 2
Hired = 6
Departed = 6

[employee__keys]
ID_Employee = N

[employee_has_hardware]
ID_Employee = 129
ID_HW = 129

asset.links.ini <--- contient les liens entre les tables

exemple :
[employee]
ID_Title=title:ID_Title
ID_Function=function:ID_
ID_Dept=department:ID_Dept
ID_StatEmp=statusemployee:ID_StatEmp

[employee_has_hardware]
ID_Employee=employee:ID_Employee
ID_HW=hardware:ID_HW

[pc]
ID_HW=hardware:ID_HW

[hardware]
ID_Lease=lease:ID_Lease
ID_Location=location:ID_Location
ID_Vendor=vendor:ID_Vendor
ID_Asset=assettype:ID_Asset
ID_Status=status:ID_Status
ID_Lease=leasing:ID_Leasing;

Si tout est bien configuré, il suffit, à présent de lancer la commande d'auto-génération :
Sous Windows (désolé mais pas encore essayé sous Linux mais ce doit être plus ou moins la même commande) :
(à partir d'un shell prompt bien sur :... mon serveur est sur le drive Y:\ )

y:\
cd \usr\local\php
php.exe Y:\usr\local\Php\pear\DB\DataObject\CreateTables.php

Ceci va permettre la génération des classes a partir de la base de données ... Chaque classe sera copiée dans le répertoire défini dans Data

Voici un exemple de classe générée par DataObject :

<?php
/* Table Definition for employee */

require_once 'DataObject.php';

class DataObjects_Employee extends DB_DataObject
{
    ###START_AUTOCODE
    /* the code below is auto generated do not remove the above tag */

    var $__table ='employee';  // table name
    var$ID_Employee;              // int(11)  not_null primary_key multiple_key auto_increment
    var$ID_Title;                       // int(11) 
    var$ID_Function;                // int(11) 
    var$ID_Dept;                      // int(11) 
    var$ID_StatEmp;                // int(11) 
    var$LastName;                  // string(30) 
    var$FirstName;                  // string(30) 
    var$Login;                         // string(18) 
    var$PhoneExt;                   // string(18) 
    var$Hired;                          // date(10) 
    var$Departed;                   // date(10) 

    /* ZE2 compatibility trick*/
    function __clone() { return $this;}

    /* Static get */
    function staticGet($k,$v=NULL) { return DB_DataObject::staticGet('DataObjects_Employee',$k,$v); }

    /* the code above is auto generated do not remove the tag below */
    ###END_AUTOCODE                
}

Une fois ceci en place, vous pouvez utiliser toute les fonctions de DataObject.

Personnellement, j'ajoute encore un fichier que j'ai nommé DO.php, dans le root de mon site, afin de m'assurer que le package DataObject est bien appelé :

<?php

require_once('PEAR.php');
$options = &PEAR::getStaticProperty('DB_DataObject','options');
$config = parse_ini_file('db/DataObject/DataObject.ini',TRUE);
$options=$config['DB_DataObject'];
?>

Récapitulons...

  • Package PEAR (DB, DataObject) dans /usr/local/PHP/PEAR
  • DataObject.ini et DOConfig.ini dans /user/local/PHP/PEAR/DB/DataObject
  • DO.php dans le root du site (www/AssetManagement)
  • Répertoire Classes (ou le nom précisé dans DataObject.ini) dans le root du site
  • Répertoire Ini (ou le nom précisé dans DataObject.ini) dans le root du site

Utilisation

Comme un bon exemple vaut mieux que mille lignes d'explication :
ici on veut recuperer le nom de tout les PC de la base de données ... :

<?php
//1 :
    require_once('do.php');
//2 :
    require_once('classes/pc.php');
//3 :
     DB_DataObject::debugLevel(0);
//4 :
    $pc = new DataObjects_Pc;
//5 :
    $number_of_rows = $pc->find();
//6 :
    while ($pc->fetch()) {
        echo '<p>PC Name : '.$pc->Name.'<br>Serial : '.{$pc->Serial}.'  <p>';
        print_r($pc); 
    }
?>

1 et 2 : on ajoute le module appellant la classe (DO.php) et on ajoute la classe que l'on va utiliser (pc.php)
3 : DebugLevel(0) en mettant a 1, on peut voir toutes les connexions à la base de données ... permet parfois de voir si il y a un problème de liens ou non ...
4 : on crée un object instance de la classe PC
5 : on récupère tout les PC et on stocke le total
6 : on boucle dans les résultats pour les afficher ($pc->Name)

Vous remarquerez, pas de connexion, pas de requête SQL... C'est beau...

Autre exemple un peu plus complexe :

    <?php
    // trying to retrieve employee id
    require_once('/www/AssetManagement/do.php');
    require_once('/www/AssetManagement/classes/employee.php');
    $employee = new DataObjects_employee;
    DB_DataObject::debugLevel(0);
    $tablehead=array();
    $tabledata=array(); 
    // $array2pass,se trouve des variables passées par paramètres , j'ai coupe par clarté
    // ce qui est intéressantici c'est la fonction whereadd dans laquelle on ajoute une clause //« WHERE »a la requête SQL ... ici on fait une recherche globale donc la requête est « %requête% »
          foreach ($array2pass as $a)
                {
                //1 :      
                            $wheresql="$a[0] like\"%$a[1]%\" "; #echo $wheresql."\n";
                //2 :        
                            $employee->whereAdd($wheresql);
            $tablehead[]=$a[0];
            $tabledata[]=$a[1];
                }
                 //3 :  
                            $nb=$employee->find();
              if ($nb> 0) {  // if there is some employeeto display
                 $tabledata=array();
                //4 :       
                           while ($employee->fetch())
                           {
                                       #print_r($employee);
                                       $row=$employee->ID_Employee;#echo$row.'<br />'."\n";
               // 5 :     
                            $tabletemp=GetEmployeeData($row);
                            $tabledata=array_merge($tabledata,$tabletemp[1]);
                            $returndata[0]=$tabletemp[0];
                           }

    }
        $returndata[1]=$tabledata;
    }
    $emphead=$returndata[0];
    $empdata=$returndata[1];
    if (empty($empdata))
    {
        echo 'No datafound <br />'."\n";
    }
    else
    {
       // 6 :     $tbl=DisplayTable($emphead,$empdata,$styletable='smtTable',$stylehead='smtHeader');
        //7 :   
               echo $tbl;
    }
    ?>

1 : on crée une requête « WHERE »
2 : on ajoute la requête à l'objet (employee->whereAdd($wheresql); )
3 : une fois toutes les clauses Where ajoutées, on lance la recherche
4 : on récupère les données répondant à la requête et on les stocke dans un tableau
5 : Fonction GetEmployeeData($row), je récupère les données de la table employee a partir du numéro du champs ... (je détaille cette fonction plus bas)
6 : Fonction pour l'affichage du tableau repris dans http://www.phpcs.com/code.aspx?id=30609
7 : on imprime le tableau

La fonction GetEmployeeData :

 Toujours selon lemême principe :

     function GetEmployeeData($ID='')
    {
        require_once('/www/AssetManagement/do.php');
        require_once('/www/AssetManagement/classes/employee.php');
        $employee = newDataObjects_employee;
        DB_DataObject::debugLevel(0);
        if (!empty($ID)){$employee->ID_Employee=$ID;}      //matching Employee ID with passed ID
        $nb=$employee->find();              // finding Employee
           if ($nb == 0)
        {
            return(array('')); exit;           //if no Employee found with match id, return blank array
        }
        $empdata=array();                //preparing array to return
        $emphead=array();

         while($employee->fetch())               //Getting Employee Data
        {
           $employee->getLinks();          // Getting linked table data
            $emphead='"ID","FirstName","Last Name","Login","PhoneExt.","Hired","Departed","Department","DIERCODE","Title","Function","Status"';
            $empdata[]=de_empty($employee->ID_Employee);   // la fonction de_empty retourne juste "_" au cas ou la valeur estvide, juste pour ne pas avoir de case vide dans le tableau
            $empdata[]=de_empty($employee->FirstName);
            $empdata[]=de_empty($employee->LastName);
            $empdata[]=de_empty($employee->Login);
            $empdata[]=de_empty($employee->PhoneExt);
            $empdata[]=de_empty($employee->Hired);
            $empdata[]=de_empty($employee->Departed);
            $empdata[]=de_empty($employee->_ID_Dept->Department);
            $empdata[]=de_empty($employee->_ID_Dept->DIERCODE);
            $empdata[]=de_empty($employee->_ID_Title->Title);
            $empdata[]=de_empty($employee->_ID_Function->Function);
            $empdata[]=de_empty($employee->_ID_StatEmp->Status);
        }
        $returndata=array($emphead,$empdata);
        return($returndata); 
    }

J'ai séparé cette fonction du reste du code car je l'utilise à plusieurs places...

Ce qui est intéressant ici c'est la fonction GetLinks :

Comme précisé plus haut, dans le répertoire ini, on trouve 2 fichiers : asset.ini contenant la définition de la base de données et asset.links.ini
Grâce à ce fichier, on lie les tables entres elles... C'est ici que la fonction getLinks() est intéressante car elle va permettre de récupérer les éléments liés :

Dans ma table, la table employee est liée à la table Department par le champ ID_Dept ...
[employee]
ID_Dept=department:ID_Dept
donc on récupère les valeurs de la table department par :
$employee->_ ID_Dept->Department ...

Donc une seule requête pour récupérer toutes les valeurs que l'on a besoin ... C'est pas beau la vie ...
Voila... j'espère avoir aidé à éclaircir l'utilisation de PEAR ::DataObject ...

Les exemples de code repris ici font partie d'une série de scripts que j'utilise pour mon site et fonctionnent sans problèmes. J'ai juste un peu allégé le code des différentes structures de contrôle et de passage de paramètres ainsi que pour l'affichage des data ...

La liste complète des fonctions de PEAR ::DataObject se trouve sur le site de PEAR comme indiqué au début...

A bientôt

A voir également
Ce document intitulé « Pear_dataobject » issu de CodeS SourceS (codes-sources.commentcamarche.net) est mis à disposition sous les termes de la licence Creative Commons. Vous pouvez copier, modifier des copies de cette page, dans les conditions fixées par la licence, tant que cette note apparaît clairement.
Rejoignez-nous