今のバージョンでやや強引にやろうとすると↓な感じ
<?php
use Zend\Db\Sql\Sql;
use Zend\Db\Sql\Select;
use Zend\Db\Sql\Platform\Mysql\Mysql as PlatformMysql;
use Zend\Db\Sql\Platform\Mysql\SelectDecorator;
use Zend\Db\Adapter\AdapterInterface;
use Zend\Db\Adapter\ParameterContainer;
use Zend\Db\Adapter\StatementContainerInterface;
$adapter = include 'bootstrap.php';
class MySelectDecorator extends SelectDecorator
{
public function prepareStatement(AdapterInterface $adapter, StatementContainerInterface $statementContainer)
{
// ensure statement has a ParameterContainer
$parameterContainer = $statementContainer->getParameterContainer();
if (!$parameterContainer instanceof ParameterContainer) {
$parameterContainer = new ParameterContainer();
$statementContainer->setParameterContainer($parameterContainer);
}
$sqls = array();
$parameters = array();
$platform = $adapter->getPlatform();
$driver = $adapter->getDriver();
foreach ($this->specifications as $name => $specification) {
//$parameters[$name] = $this->{'process' . $name}($platform, $driver, $parameterContainer, $sqls, $parameters);
$parameters[$name] = $this->select->{'process' . $name}($platform, $driver, $parameterContainer, $sqls, $parameters);
if ($specification && is_array($parameters[$name])) {
$sqls[$name] = $this->select->createSqlFromSpecificationAndParameters($specification, $parameters[$name]);
}
}
//$sqls[] = 'FOR UPDATE';
$sqls[] = 'LOCK IN SHARE MODE';
$sql = implode(' ', $sqls);
$statementContainer->setSql($sql);
return;
}
}
$sql = new Sql($adapter, null , new PlatformMysql(new MySelectDecorator));
$select = $sql->select()->from('news')->where(['id' => 1]);
$statement = $sql->prepareStatementForSqlObject($select);
$results = $statement->execute(); // SELECT `news`.* FROM `news` WHERE `id` = '1' LOCK IN SHARE MODE
まじめにやるならZend\Db\Sql\Selectのspecificationsにキー用意して、processForUpdateメソッドの実装とかresetとかを実装しなきゃいけないのは置いといて、そもそも
Zend\Db\Sql\Platform*\SelectDecoratorたちは各プラットフォームの差異の吸収が目的っぽいのでSelectDecoratorだけのspecificationが存在しては一貫性なさそうでダメそう。