简体   繁体   中英

ZF2 Between Dates

I've been unable to successfully retrieve records between two dates in Zend Framework 2.

My code looks as follows:

 $select = $this->getTimeTable();
 $predicate = new  \Zend\Db\Sql\Where();
 $select->where($predicate->between("start_date", $week_sunday_date , $satruday_date));

 public function getTimeTable()
    {
            if (!$this->timeTable)
            {
                    $this->timeTable = new TableGateway(
                            'time',
                            $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter')

                    );
            }
            return $this->timeTable;
    }

"start_date" is the column in my DB that is of type DATETIME, and $week_sunday_date , $satruday_date are both generated as follows

  $week_sunday_date = date("Y-m-d\TH:i:sP",strtotime('this sunday'));
 $satruday_date = date("Y-m-d\TH:i:sP",strtotime("+6 day", strtotime($week_sunday_date)));

The database connection is good and I can otherwise get data. Dumping both $week_sunday_date and $satruday_date variables above I see:

string(25) "2014-11-08T00:00:00+00:00" string(25) "2014-11-02T00:00:00+00:00"

I've also tried several other ways of in between but ultimately the page is blank and won't load due to an error.

Seems like I need something like this:

$statement = $sql->prepareStatementForSqlObject($select);
$time_list = $statement->execute();

But not sure how to initialize $sql properly.

I think the correct syntax would be:

$select->where->between('start_date', $week_sunday_date, $saturday_date);

Oh, but since, in your case $select is an instance of TableGateway, then you probably need $select->getSql()->where->between(...) .


I'm a little rusty on TableGateway, we've strayed away from using it. But I think you can do something like:

$timeTable = new TableGateway(/*...*/);
$select = $timeTable->getSql()->select();
$select->columns(array('col1', 'col2'));
$select->where->between('start_date', $week_sunday_date, $saturday_date);
$resultSet = $timeTable->selectWith($select);
var_dump($resultSet->toArray());

Note: I do not recommend always converting the result set to an array, but it's nice to be able to do this for debugging purposes.


Example not using TableGateway:

Query class:

namespace Example\Model\Sql\Select;

use Zend\Db\Sql\Select;

class Time extends Select {

    public function __construct($week_sunday_date, $saturday_date) {
        parent::__construct(['t' => 'Time']);

        $this->columns([
            'col1',
            'col2',
        ]);

        $this->where->between('start_date', $week_sunday_date, $saturday_date);
    }
}

Data model: (basically a glorified array object, just holds data, no business logic)

namespace Example\Model\DataContainer;

class Time extends \ArrayObject {

    protected $col1;
    protected $col2;

    public function exchangeArray($data) {
        $this->col1 = $data['col1'];
        $this->col2 = $data['col2'];
    }

    public function getCol1() {
        return $col1;
    }

    public function getCol2() {
        return $col2;
    }
}

Controller:

namespace Example\Controller;

use Example\Model\DataContainer;
use Example\Model\Sql\Select;
use Zend\Db\ResultSet\ResultSet;

class IndexController {

    public function myExampleAction() {
        $request = $this->getRequest();
        $sm = $this->getServiceLocator();

        $query = new Select\Time($request->getQuery('sunday'), $request->getQuery('saturday'));
        $resultSet = new ResultSet(ResultSet::TYPE_ARRAYOBJECT, new DataContainer\Time());

        $executer = $sm->get('Executer');
        $resultSet = $executer->execute($query, $resultSet);

        return [
            'time' => $resultSet, // loop through results in your view
        ];
    }
}

So, we create an instance of our query class, which is set up when you call the constructor implicitly by creating a new instance of it. We pass our parameters into it. Then, we create an instance of our result set class, and we specify the array object prototype. Each row returned by our query will be populated as an instance of the array object prototype. When the result set is initialized, it will automatically call exchangeArray() with the data returned for the current row. That method populates your data container, and so the result set is populated with an array of these populated data container objects. So when you loop through the result set, each row will be represented by an instance of your array object prototype.

You will have to define your own Executer class. That's not a built-in. You will have to create it and add it to the service config, so that you can get it out of the service manager like I've done in the example.

A quick example for the $sql property as you requested at the end of your question. You should use: use Zend\\Db\\Sql\\Sql; use Zend\\Db\\Sql\\Select;

$adapter = $this->tableGateway->getAdapter();//get connection
$sql = new Sql($adapter);
$select = $sql->select();
$select->from($this->tableGateway->getTable())->where(array('active' => '1'));
$selectString = $sql->getSqlStringForSqlObject($select);
    //echo $selectString;die;//this will show the quesry string build above.
$results = $adapter->query($selectString, $adapter::QUERY_MODE_EXECUTE);
$resultSet = new ResultSet();
$resultSet->initialize($results);

return $resultSet->toArray();//return array(use $resultSet->current() for one row)

i hope this helps

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM