ZendFramework2学习笔记 “单表多对象”的CRUD操作、“多表单对象”的CRUD操作

    CRUD是指增加(Create)、读取(Retrieve)、更新(Update)和删除(Delete)几个单词的首字母简写。

    在ZendFramework2项目中建立一个模块Test。

    Test模块的module.config.php的控制器和路由这样配置:

<span style="font-size:18px;"> 'controllers' => array(
         'invokables' => array(
             'Test\Controller\Test' => 'Test\Controller\TestController',
         ),
     ),
    'router' => array(
         'routes' => array(
             'test' => array(
                 'type'    => 'segment',
                 'options' => array(
                     'route'    => '/test[/][:action][/:id]',
                     'constraints' => array(
                         'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
                         'id'     => '[0-9]+',
                     ),
                     'defaults' => array(
                         'controller' => 'Test\Controller\Test',
                         'action'     => 'tdb',
                     ),
                 ),
             ),
         ),
     ),</span>
 

一)单表单对象的CRUD操作

    在数据库中创建这样一个表:

CREATE TABLE `a` (
  `name` varchar(255) NOT NULL,
  `content` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    单表单对象的CRUD操作实现起来相对简单,可以参考ZendFramework2的例子程序Album模块。

    在Modules\Test\src\Model\下创建文件“A.php”和“ATable.php”

    A.php内容如下:

namespace Test\Model;

class A {
    
    public $name;
    public $content;
    
    
    public $type;
    
    public function __construct() {
    }

    public function exchangeArray($data) {
        $this->name = empty($data['name']) ? null : $data['name'];
        $this->content = empty($data['content']) ? null : $data['content'];

        
        $this->type = empty($data['type']) ? null : $data['type'];
    }
     
    //binding Model to Form needs this method 
    public function getArrayCopy() {
        return get_object_vars($this);
    }
     
}

其中exchangeArray函数会被框架调用,其参数$data是一个从表a获取的以表a的字段名/字段值为key/value的关联数组,该函数用于填充对象。

其中getArrayCopy函数是将对象按对象属性/属性值为key/value转换为关联数组。

    ATable.php类容如下:

namespace Test\Model;

use Zend\Db\TableGateway\TableGateway;
use Zend\Db\Sql\Where;
use Zend\Db\Sql\Predicate\Operator;

class ATable {
    
    protected $tableGateway;
    
    public function __construct(TableGateway $tableGateway) {
        $this->tableGateway = $tableGateway;
    }
     
    public function select($where=null) {
        $resultSet = $this->tableGateway->select($where);
        return $resultSet;
    }
        
    public function update($a) {
        if (!($a instanceof A)) {
            return false;
        }
        //检查要修改的记录主键是否存在
        $where = new Where();
        $where->addPredicate(new Operator('name', Operator::OPERATOR_EQUAL_TO, $a->name));
        $resultSet = $this->tableGateway->select($where);
        if (count($resultSet) > 0) {
            $data = $a->getArrayCopy();
            unset($data['name']);//移除主键
            try {
                $ret = $this->tableGateway->update($data, array('name' => $a->name));
                if ($ret == 1 || $ret == 0) {
                    return true;
                }
            } catch (Exception $ex) {

            }
        }        
        return false;
    }
    
    public function insert($a) {
        if (!($a instanceof A)) {
            return false;
        }
        //检查要修改的记录主键是否存在
        $where = new Where();
        $where->addPredicate(new Operator('name', Operator::OPERATOR_EQUAL_TO, $a->name));
        $resultSet = $this->tableGateway->select($where);
        if (count($resultSet) > 0) {
            return false;
        }
        try {
            $data = $a->getArrayCopy();
            $ret = $this->tableGateway->insert($data);
            if ($ret == 1) {
                return true;
            }
        } catch (Exception $ex) {

        }
        return false;
    }     
     
    public function delete($a) {
        if (!($a instanceof A)) {
            return false;
        }
        try {
            $ret = $this->tableGateway->delete(array('name' => $a->name));
            if ($ret == 1) {
                return true;
            }
        } catch (Exception $ex) {

        }
        return false;
    }
}

该类是表a的操作类,具体实现select、update、delete、insert操作。

打开Module\Test\Module.php文件,添加getServiceConfig函数:

    public function getServiceConfig()
    {
        return array(
            'factories' => array(
                'Test\Model\ATable' =>  function($sm) {
                    $tableGateway = $sm->get('ATableGateway');
                    $table = new ATable($tableGateway);
                    return $table;
                },
                'ATableGateway' => function ($sm) {
                    $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                    $resultSetPrototype = new ResultSet();
                    $resultSetPrototype->setArrayObjectPrototype(new A());
                    return new TableGateway('a', $dbAdapter, null, $resultSetPrototype);
                },
        );
    }
    其中,ResultSet->setArrayObjectPrototype就是执行ATable->select函数时,ZendFramework2框架自动将表记录转换为的对象原型。

    并添加类引用:

use Test\Model\A;
use Test\Model\ATable;

    在Module\Test\src\Test\Controller\TestController.php中添加对象A的CRUD四个控制器:

namespace Test\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\Db\Sql\Where;
use Zend\Db\Sql\Predicate\Operator;

use Test\Model\A;

class TestController extends AbstractActionController {
    
    protected $aTable;
    
    public function getATable() {
        if (!$this->aTable) {
            $sm = $this->getServiceLocator();
            $this->aTable = $sm->get('Test\Model\ATable');
        }
        return $this->aTable;
    }
    
    public function selectAction() {      
        $name = $this->params()->fromQuery('name');
        if (!empty($name)) {
            $where = new Where();
            $where->addPredicate(new Operator('name', Operator::OPERATOR_EQUAL_TO, $name));
        }
        
        return new ViewModel(array(
            'as' => $this->getATable()->select((isset($where)?$where:null)),
        ));
    }
     
    public function insertAction() {
        $name = $this->params()->fromQuery('name');
        if (empty($name)) {
            $name = 'name';
        }
        $a = new A;
        $a->name = $name;
        $a->content = "content";
        $ret = $this->getATable()->insert($a);
        
        return new ViewModel(array(
            'ret' => ($ret==false?"false":"true"),
        ));
    }
    
    public function updateAction() {
        $name = $this->params()->fromQuery('name');
        if (empty($name)) {
            $name = 'name';
        }
        $content = $this->params()->fromQuery('content');
        if (empty($content)) {
            $content = 'content';
        }
        $a = new A;
        $a->name = $name;
        $a->content = $content;
        $ret = $this->getATable()->update($a);
         
        return new ViewModel(array(
            'ret' => ($ret==false?"false":"true"),
        ));
    }
    
    public function deleteAction() {
        $name = $this->params()->fromQuery('name');
        if (empty($name)) {
            $name = 'name';
        }
        
        $a = new A;
        $a->name = $name;
        $ret = $this->getATable()->delete($a);
        
        return new ViewModel(array(
            'ret' => ($ret==false?"false":"true"),
        ));
    }
    
}

最后在Module\Test\view\test\test\目录下新建select.phtml、insert.phtml、update.phtml和delete.phtml:

//select.phtml

 $title = 'select';
 $this->headTitle($title);
 ?>
 <h1><?php echo $this->escapeHtml($title); ?></h1>

 <?php 
    foreach ($this->as as $a) {
        echo $this->escapeHtml($a->name);
        echo "------";
        echo $this->escapeHtml($a->content);
        echo "<br/>";
    }


 //insert.phtml

  $title = 'insert';
 $this->headTitle($title);
 ?>
 <h1><?php echo $this->escapeHtml($title); ?></h1>

 <?php 
        echo $this->ret;
        echo "<br/>";


 //update.phtml
 $title = 'update';
 $this->headTitle($title);
 ?>
 <h1><?php echo $this->escapeHtml($title); ?></h1>

 <?php 
        echo $this->ret;
        echo "<br/>";


 //delete.phtml
 $title = 'delete';
 $this->headTitle($title);
 ?>
 <h1><?php echo $this->escapeHtml($title); ?></h1>

 <?php 
        echo $this->ret;
        echo "<br/>";

读取(Retrieve)使用http://xxxx/test/select或者http://xxx/test/select?name=y。

增加(Create)使用http://xxx/test/insert?name=y。

更新(Update)使用http://xxx/test/insert?name=y&content=z。

删除(Delete)使用http://xxx/test/delete?name=y。


二)单表多对象的CRUD操作

假设有这样一种类关系:class b;为基类,class B1;和class B2;分别各自从class b;继承,而B1和B2的对象存入数据库时,都是存在一张表里面,这种情况下,一张表的记录record就可能转换为B1和B2多种类的对象。

在数据库中创建这样一个表:

CREATE TABLE `b` (
  `name` varchar(255) NOT NULL,
  `content` varchar(255) DEFAULT NULL,
  `type` varchar(40) DEFAULT NULL,//type=='B1'代表是B1存储而来,type=='B2'代表是B2存储而来
  `contentB1` varchar(255) DEFAULT NULL,
  `contentB2` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    在Modules\Test\src\Model\下创建文件“B.php”、“B1.php”、“B2.php”和“BTable.php”

B.php内容如下:

namespace Test\Model;

class B {
    
    public $name;
    public $content;
    public $type;
    
    public function __construct() {
    }

    public function exchangeArray($data) {
        $this->name = empty($data['name']) ? null : $data['name'];
        $this->content = empty($data['content']) ? null : $data['content'];
        $this->type = empty($data['type']) ? null : $data['type'];
    }
     
    public function getArrayCopy() {
        return get_object_vars($this);
    }
     
}
    B1.php内容如下:

namespace Test\Model;

use Test\Model\B;

class B1 extends B{
    
    public $contentB1;
    
    public function __construct() {
    }

    public function exchangeArray($data) {
        parent::exchangeArray($data);
        $this->contentB1 = empty($data['contentB1']) ? null : $data['contentB1'];
     }
     
    public function getArrayCopy() {
        return get_object_vars($this);
    }
}
    B2.php内容如下:

namespace Test\Model;

use Test\Model\B;

class B2 extends B{
    
    public $contentB2;
    
    public function __construct() {
    }

    public function exchangeArray($data) {
        parent::exchangeArray($data);
        $this->contentB2 = empty($data['contentB2']) ? null : $data['contentB2'];
     }
     
    public function getArrayCopy() {
        return get_object_vars($this);
    }
}

BTable.php内容如下:

namespace Test\Model;

use Zend\Db\TableGateway\TableGateway;
use Zend\Db\Sql\Where;
use Zend\Db\Sql\Predicate\Operator;

use Test\Model\B;
use Test\Model\B1;
use Test\Model\B2;

class BTable {
    protected $tableGateway;
    
    public function __construct(TableGateway $tableGateway) {
        $this->tableGateway = $tableGateway;
    }
     
    public function select($where=null) {
        $resultSet = $this->tableGateway->select($where);
        //由于module.php里面指定返回的是关联数组,因此此处要编写关联数组转为对象数组的代码
        $resultSetObjs = array();
        foreach ($resultSet as $rec) {
            $type = $rec['type'];
            if (empty($type)) {
                $obj = new B();
            } else if ($type == 'B1') {
                $obj = new B1();
            } else {
                $obj = new B2();
            }
            $obj->exchangeArray($rec);
            $resultSetObjs[] = $obj;
        }
        return $resultSetObjs;
    }
        
    public function update($b) {
        if (!($b instanceof B) &&
                !($b instanceof B1) &&
                !($b instanceof B2)) {
            return false;
        }
        //检查要修改的记录主键是否存在
        $where = new Where();
        $where->addPredicate(new Operator('name', Operator::OPERATOR_EQUAL_TO, $b->name));
        $resultSet = $this->tableGateway->select($where);
        if (count($resultSet) > 0) {
            $data = $b->getArrayCopy();
            unset($data['name']);//移除主键
            try {
                $ret = $this->tableGateway->update($data, array('name' => $b->name));
                if ($ret == 1 || $ret == 0) {
                    return true;
                }
            } catch (Exception $ex) {

            }
        }        
        return false;
    }
    
    public function insert($b) {
        if (!($b instanceof B) &&
                !($b instanceof B1) &&
                !($b instanceof B2)) {
            return false;
        }
        //检查要修改的记录主键是否存在
        $where = new Where();
        $where->addPredicate(new Operator('name', Operator::OPERATOR_EQUAL_TO, $b->name));
        $resultSet = $this->tableGateway->select($where);
        if (count($resultSet) > 0) {
            return false;
        }
        try {
            $data = $b->getArrayCopy();
            $ret = $this->tableGateway->insert($data);
            if ($ret == 1) {
                return true;
            }
        } catch (Exception $ex) {

        }
        return false;
    }     
     
    public function delete($b) {
        if (!($b instanceof B) &&
                !($b instanceof B1) &&
                !($b instanceof B2)) {
            return false;
        }
        try {
            $ret = $this->tableGateway->delete(array('name' => $b->name));
            if ($ret == 1) {
                return true;
            }
        } catch (Exception $ex) {

        }
        return false;
    }
}

打开Module\Test\Module.php文件,修改getServiceConfig函数:

    public function getServiceConfig()
    {
        return array(
            'factories' => array(
                'Test\Model\ATable' =>  function($sm) {
                    $tableGateway = $sm->get('ATableGateway');
                    $table = new ATable($tableGateway);
                    return $table;
                },
                'ATableGateway' => function ($sm) {
                    $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                    $resultSetPrototype = new ResultSet();
                    $resultSetPrototype->setArrayObjectPrototype(new A());
                    return new TableGateway('a', $dbAdapter, null, $resultSetPrototype);
                },
                'Test\Model\BTable' =>  function($sm) {
                    $tableGateway = $sm->get('BTableGateway');
                    $table = new BTable($tableGateway);
                    return $table;
                },
                'BTableGateway' => function ($sm) {
                    $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                    //指定结果集是array,就可以阻止tableGateway将结果集的记录映射成对象
                    //这是就需要在BTable的select函数里手动将数组转换为对象
                    $resultSetPrototype = new ResultSet(ResultSet::TYPE_ARRAY);
                    return new TableGateway('a', $dbAdapter, null, $resultSetPrototype);
                },
            ),
        );
    }

    其中new ResultSet(ResultSet::TYPE_ARRAY);TYPE_ARRAY的作用是让ZendFramework2框架将结果集作为关联数组返回,之后就可以在BTable里面通过代码将记录集转换为不同对象了。

在Module\Test\src\Test\Controller\TestController.php中添加对象B、B1、B2的CRUD四个控制器:

class TestController extends AbstractActionController {
    
    protected $bTable;
    
    public function getBTable() {
        if (!$this->bTable) {
            $sm = $this->getServiceLocator();
            $this->bTable = $sm->get('Test\Model\BTable');
        }
        return $this->bTable;
    }

    public function selectbAction() {      
        $name = $this->params()->fromQuery('name');
        if (!empty($name)) {
            $where = new Where();
            $where->addPredicate(new Operator('name', Operator::OPERATOR_EQUAL_TO, $name));
        }
        
        $resultSet = $this->getBTable()->select((isset($where)?$where:null));   

        return new ViewModel(array(
            'bs' => $resultSet,
        ));
    }
    public function deletebAction() {
        $name = $this->params()->fromQuery('name');
        if (empty($name)) {
            $name = 'name';
        }
        
        $b = new B;
        $b->name = $name;
        $ret = $this->getBTable()->delete($b);
        
        return new ViewModel(array(
            'ret' => ($ret==false?"false":"true"),
        ));
    }
    public function updatebAction() {
        $name = $this->params()->fromQuery('name');
        if (empty($name)) {
            $name = 'name';
        }
        $b = new B1;
        $b->name = $name;
        $b->content = 'new content';
        $b->type = 'B1';
        $b->contentB1 = 'B1';
        /*
        $b = new B2;
        $b->name = $name;
        $b->content = 'new content';
        $b->type = 'B2';
        $b->contentB2 = 'B2';
         */
        $ret = $this->getBTable()->update($b);
         
        return new ViewModel(array(
            'ret' => ($ret==false?"false":"true"),
        ));
    }
    public function insertbAction() {
        $name = $this->params()->fromQuery('name');
        if (empty($name)) {
            $name = 'name';
        }
        $b = new B2;
        $b->name = $name;
        $b->content = "b2 content";
        $b->type = 'B2';
        $b->contentB2 = 'B2';
        /*
        $b = new B2;
        $b->name = $name;
        $b->content = "b2 content";
        $b->type = 'B2';
        $b->contentB2 = 'B2';
         */
        $ret = $this->getATable()->insert($b);
        
        
        
        return new ViewModel(array(
            'ret' => ($ret==false?"false":"true"),
        ));
    }
}

同时记得添加引用:

use Test\Model\B;
use Test\Model\B1;
use Test\Model\B2;

最后在Module\Test\view\test\test\目录下新建selectb.phtml、insertb.phtml、updateb.phtml和deleteb.phtml:

//selectb.phtml

 $title = 'selectB';
 $this->headTitle($title);
 ?>
 <h1><?php echo $this->escapeHtml($title); ?></h1>

 <?php 
    foreach ($this->bs as $b) {
        echo $this->escapeHtml($b->name);
        echo "------";
        echo $this->escapeHtml($b->content);
        echo "------";
        echo $this->escapeHtml($b->type);
        echo "------get_class:";
        echo $this->escapeHtml(get_class($b));
        echo "<br/>";
    }


//insertb.phtml

 $title = 'insertB';
 $this->headTitle($title);
 ?>
 <h1><?php echo $this->escapeHtml($title); ?></h1>

 <?php 
        echo $this->ret;
        echo "<br/>";


//updateb.phtml

 $title = 'updateB';
 $this->headTitle($title);
 ?>
 <h1><?php echo $this->escapeHtml($title); ?></h1>

 <?php 
        echo $this->ret;
        echo "<br/>";


//deleteb.phtml

 $title = 'deleteB';
 $this->headTitle($title);
 ?>
 <h1><?php echo $this->escapeHtml($title); ?></h1>

 <?php 
        echo $this->ret;
        echo "<br/>";

读取(Retrieve)使用http://xxxx/test/selectb或者http://xxx/test/selectb?name=y。

增加(Create)使用http://xxx/test/insertb?name=y。

更新(Update)使用http://xxx/test/insertb?name=y。

删除(Delete)使用http://xxx/test/deleteb?name=y。


三)多表单对象的CRUD操作

假设有这样一种类关系:class Main;类中有个数组protected $path = array();将Main对象存入数据库时,可能将$path单独存入一张assisttable表,这样情况下,多张表的多条记录records才转成类Main的一个对象。
    在数据库中创建2张表:
CREATE TABLE `maintable` (
  `name` varchar(255) NOT NULL,
  `content` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `assisttable` (
  `mainName` varchar(255) NOT NULL,
  `path` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

maintable表的name字段和assisttable的mainName字段是一对多的关系。

在Modules\Test\src\Model\下创建文件“Main.php”、“MainTable.php”和“MaintableFeature.php“。

Main.php内容如下:

namespace Test\Model;

class Main {
    
    public $name;
    public $content;    
    public $path = array();
    
    public function __construct() {
    }
     
    public function getArrayCopy() {
        return get_object_vars($this);
    }
     
}

其中类Main没有实现exchangeArray函数。

MainTable.php内容如下:

namespace Test\Model;

use Zend\Db\TableGateway\TableGateway;
use Zend\Db\Sql\Where;
use Zend\Db\Sql\Predicate\Operator;
use Zend\Db\Sql\Sql;
use Zend\Db\Sql\Select;


use Test\Model\Main;

class MainTable {
    protected $tableGateway;
    
    public function __construct(TableGateway $tableGateway) {
        $this->tableGateway = $tableGateway;
    }
     
    public function select($where=null) {
        $selectFeature = new MaintableFeature('assisttable');
        $selectFeature->setParamsForSelect('maintable.name=assisttable.mainName');
        $this->tableGateway->getFeatureSet()->addFeature($selectFeature);
        $resultSet = $this->tableGateway->select($where);
        //将结果集转换为对象数组
        $count = 1;
        $nameArray = array();
        $objectArray = array();
        foreach ($resultSet as $rec){
            $key = array_search($rec['name'], $nameArray);
            if (empty($key)) {
                $nameArray[$count] = $rec['name'];
                $objectArray[$count] = new Main();
                $objectArray[$count]->name = $rec['name'];
                $objectArray[$count]->content = (empty($rec['content'])?null:$rec['content']);
                if (!empty($rec['path'])) {
                    $objectArray[$count]->path[] = $rec['path'];
                }
                $count++;
            } else {
                if (!empty($rec['path'])) {
                    $objectArray[$key]->path[] = $rec['path'];
                }
            }
        }        
        return $objectArray;
    }
    
    public function insert($main) {
        if (!($main instanceof Main)) {
            return false;
        }
        //检查要修改的记录主键是否存在
        $where = new Where();
        $where->addPredicate(new Operator('name', Operator::OPERATOR_EQUAL_TO, $main->name));
        $resultSet = $this->tableGateway->select($where);
        if (count($resultSet) > 0) {
            return false;
        }
        try {
            $data = $main->getArrayCopy();
            //获取要插入assisttable表的内容
            $dataAssist = array();
            foreach ($data['path'] as $path) {
                $dataAssist[] = array('mainName' => $data['name'], 'path' => $path);
            }
            $insertFeature = new MaintableFeature('assisttable');
            $insertFeature->setParamsForInsert($dataAssist);
            $this->tableGateway->getFeatureSet()->addFeature($insertFeature);
            unset($data['path']);//移除要写入到assisttable的内容
            $ret = $this->tableGateway->insert($data);
            if ($ret == 1) {                
                return true;
            }
        } catch (Exception $ex) {

        }
        return false;
    }      
    
    public function delete($main) {
        if (!($main instanceof Main)) {
            return false;
        }
        try {
            $deleteFeature = new MaintableFeature('assisttable');
            $deleteFeature->setParamsForDelete($main->name);
            $this->tableGateway->getFeatureSet()->addFeature($deleteFeature);
            $ret = $this->tableGateway->delete(array('name' => $main->name));
            if ($ret == 1) {
                return true;
            }
        } catch (Exception $ex) {

        }
        return false;
    }

    public function update($main) {
        if (!($main instanceof Main)) {
            return false;
        }
        //检查要修改的记录主键是否存在
        $where = new Where();
        $where->addPredicate(new Operator('name', Operator::OPERATOR_EQUAL_TO, $main->name));
        $resultSet = $this->tableGateway->select($where);
        if (count($resultSet) > 0) {
            $data = $main->getArrayCopy();
            //获取要插入assisttable表的内容
            $dataAssist = array();
            foreach ($data['path'] as $path) {
                $dataAssist[] = array('mainName' => $data['name'], 'path' => $path);
            }
            $updateFeature = new MaintableFeature('assisttable');
            $updateFeature->setParamsForUpdate($data['name'], $dataAssist);
            $this->tableGateway->getFeatureSet()->addFeature($updateFeature);
            unset($data['path']);//移除要写入到assisttable的内容
            try {
                unset($data['name']);//移除主键
                $ret = $this->tableGateway->update($data, array('name' => $main->name));
                if ($ret == 1 || $ret == 0) {
                    return true;
                }
            } catch (Exception $ex) {

            }
        }        
        return false;
    }
}

MaintableFeature.php内容如下:

namespace Test\Model;

use Zend\Db\TableGateway\Feature\AbstractFeature;
use Zend\Db\Sql\Select;
use Zend\Db\Sql\Insert;
use Zend\Db\Sql\Delete;
use Zend\Db\Adapter\Driver\ResultInterface;
use Zend\Db\Adapter\Driver\StatementInterface;

class MaintableFeature extends AbstractFeature {

    protected $assistTable;//assistTable
    
    //select ref
    protected $onForSelect;
    protected $clumsForSelect;
    protected $methodForSelect;
    
    //insert ref
    protected $valsForInsert;
    
    //delete ref
    protected $mainNameForDelete;
    
    //update ref
    protected $valsForUpdate;
    protected $mainNameForUpdate;

    public function __construct($assistTable) {
        $this->assistTable = $assistTable;
    }

    public function setParamsForSelect($on, $clums=null, $method=null) {
        $this->onForSelect = $on;
        $this->clumsForSelect = $clums;
        $this->methodForSelect = $method;
    }
    public function preSelect(Select $select) {
         $select->join($this->assistTable, 
                 $this->onForSelect, 
                 empty($this->clumsForSelect)?Select::SQL_STAR:$this->clumsForSelect, 
                 empty($this->methodForSelect)?Select::JOIN_LEFT:$this->methodForSelect
                 ); 
    }
    
    public function setParamsForInsert($valsForInsert) {
        $this->valsForInsert = $valsForInsert;
    }
    public function postInsert(StatementInterface $statement, ResultInterface $result)
    {
        foreach ($this->valsForInsert as $vals) {
            $insert = new Insert($this->assistTable);
            $insert->values($vals);
            
            $statement = $this->tableGateway->getAdapter()->getDriver()->createStatement();        
            $insert->prepareStatement($this->tableGateway->getAdapter(), $statement);        
            $result = $statement->execute();
        }
    }
    
    public function setParamsForDelete($mainNameForDelete) {
        $this->mainNameForDelete = $mainNameForDelete;
    }
    public function postDelete(StatementInterface $statement, ResultInterface $result) {
        $delete = new Delete($this->assistTable);
        $delete->where(array('mainName' => $this->mainNameForDelete));

        $statement = $this->tableGateway->getAdapter()->getDriver()->createStatement();
        $delete->prepareStatement($this->tableGateway->getAdapter(), $statement);
        $result = $statement->execute();
    }
    
    public function setParamsForUpdate($mainNameForUpdate, $valsForUpdate) {
        $this->mainNameForUpdate = $mainNameForUpdate;
        $this->valsForUpdate = $valsForUpdate;
    }
    public function postUpdate(StatementInterface $statement, ResultInterface $result) {
        //delete asssist records first
        $delete = new Delete($this->assistTable);
        $delete->where(array('mainName' => $this->mainNameForUpdate));

        $statement = $this->tableGateway->getAdapter()->getDriver()->createStatement();
        $delete->prepareStatement($this->tableGateway->getAdapter(), $statement);
        $result = $statement->execute();
        
        //insert assist records next
        foreach ($this->valsForUpdate as $vals) {
            $insert = new Insert($this->assistTable);
            $insert->values($vals);
            
            $statement = $this->tableGateway->getAdapter()->getDriver()->createStatement();        
            $insert->prepareStatement($this->tableGateway->getAdapter(), $statement);        
            $result = $statement->execute();
        }
    }
}

MaintableFeature类主要实现tableGateway在执行select、update、delete和insert操作的时候,对关联表assisttable也执行相应操作。

打开Module\Test\Module.php文件,修改getServiceConfig函数:

   public function getServiceConfig()
    {
        return array(
            'factories' => array(
                'Test\Model\ATable' =>  function($sm) {
                    $tableGateway = $sm->get('ATableGateway');
                    $table = new ATable($tableGateway);
                    return $table;
                },
                'ATableGateway' => function ($sm) {
                    $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                    $resultSetPrototype = new ResultSet();
                    $resultSetPrototype->setArrayObjectPrototype(new A());
                    return new TableGateway('a', $dbAdapter, null, $resultSetPrototype);
                },
                'Test\Model\BTable' =>  function($sm) {
                    $tableGateway = $sm->get('BTableGateway');
                    $table = new BTable($tableGateway);
                    return $table;
                },
                'BTableGateway' => function ($sm) {
                    $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                    //指定结果集是array,就可以阻止tableGateway将结果集的记录映射成对象
                    //这是就需要在BTable的select函数里手动将数组转换为对象
                    $resultSetPrototype = new ResultSet(ResultSet::TYPE_ARRAY);
                    return new TableGateway('a', $dbAdapter, null, $resultSetPrototype);
                },
                'Test\Model\MainTable' =>  function($sm) {
                    $tableGateway = $sm->get('MainTableGateway');
                    $table = new MainTable($tableGateway);
                    return $table;
                },
                'MainTableGateway' => function ($sm) {
                    $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                    //由于查询到的结果集无法将assist表的记录集按main表的主键聚合到Main对象内
                    //因此,此处还是阻止tableGateway将结果集的记录映射成对象
                    //之后在MainTable的select函数里手动将数组转换为对象
                    $resultSetPrototype = new ResultSet(ResultSet::TYPE_ARRAY);
                    return new TableGateway('maintable', $dbAdapter, null, $resultSetPrototype);
                },
            ),
        );
    }

    在Module\Test\src\Test\Controller\TestController.php中添加对象Main的CRUD四个控制器:

class TestController extends AbstractActionController {
    
    protected $mainTable;
    
    public function getMainTable() {
        if (!$this->mainTable) {
            $sm = $this->getServiceLocator();
            $this->mainTable = $sm->get('Test\Model\MainTable');
        }
        return $this->mainTable;
    }

    public function selectmainAction() {      
        $name = $this->params()->fromQuery('name');
        if (!empty($name)) {
            $where = new Where();
            $where->addPredicate(new Operator('name', Operator::OPERATOR_EQUAL_TO, $name));
        }
        
        $resultSet = $this->getMainTable()->select((isset($where)?$where:null));   

        return new ViewModel(array(
            'mains' => $resultSet,
        ));
    }
    public function insertmainAction() {
        $name = $this->params()->fromQuery('name');
        if (empty($name)) {
            $name = 'main';
        }
        $main = new Main();
        $main->name = $name;
        $main->content = "main content";
        $main->path[] = 'path1';
        $main->path[] = 'path2';

        $ret = $this->getMainTable()->insert($main);       
        
        return new ViewModel(array(
            'ret' => ($ret==false?"false":"true"),
        ));
    }
    public function deletemainAction() {
        $name = $this->params()->fromQuery('name');
        if (empty($name)) {
            $name = 'name';
        }
        
        $main = new Main();
        $main->name = $name;
        $ret = $this->getMainTable()->delete($main);
        
        return new ViewModel(array(
            'ret' => ($ret==false?"false":"true"),
        ));
    }
    public function updatemainAction() {
        $name = $this->params()->fromQuery('name');
        if (empty($name)) {
            $name = 'name';
        }
        $main = new Main();
        $main->name = $name;
        $main->content = 'new content';
        $main->path = array();
        $main->path[] = 'patha';

        $ret = $this->getMainTable()->update($main);
         
        return new ViewModel(array(
            'ret' => ($ret==false?"false":"true"),
        ));
    }
}

同时记得添加引用:

use Test\Model\Main;
最后在Module\Test\view\test\test\目录下新建selectmain.phtml、insertmain.phtml、updatemain.phtml和deletemain.phtml:
//selectmain.phtml

 $title = 'selectMain';
 $this->headTitle($title);
 ?>
 <h1><?php echo $this->escapeHtml($title); ?></h1>

 <?php 
    foreach ($this->mains as $main) {
        echo $this->escapeHtml($main->name);
        echo "------";
        echo $this->escapeHtml($main->content);
        echo "------";
        foreach ($main->path as $path) {
            echo $this->escapeHtml($path);
            echo "------";
        }
        echo "<br/>";
    }


//insertmain.phtml

 $title = 'insertMain';
 $this->headTitle($title);
 ?>
 <h1><?php echo $this->escapeHtml($title); ?></h1>

 <?php 
        echo $this->ret;
        echo "<br/>";


//updatemain.phtml

 $title = 'updateMain';
 $this->headTitle($title);
 ?>
 <h1><?php echo $this->escapeHtml($title); ?></h1>

 <?php 
        echo $this->ret;
        echo "<br/>";


//deletemain.phtml

 $title = 'deleteMain';
 $this->headTitle($title);
 ?>
 <h1><?php echo $this->escapeHtml($title); ?></h1>

 <?php 
        echo $this->ret;
        echo "<br/>";

读取(Retrieve)使用http://xxxx/test/selectmain或者http://xxx/test/selectmain?name=y。

增加(Create)使用http://xxx/test/insertmain?name=y。

更新(Update)使用http://xxx/test/insertmain?name=y。

删除(Delete)使用http://xxx/test/deletemain?name=y。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值