#バドシス 〜 日々のことを続く限り書いてみようと思って 〜

頑張って日々のことを書いていこうと思います。

【CAKEPHP3】CAKEPHP2から移行した時のメモ

CAKEPHP2から移行するときのメモをまとめていきます。

お作法とか結構違うので色々注意が必要ですね。

 

PHPフレームワーク CakePHP 3入門

 

View系

$this->Form

Viewの『$this->Form->input』ですが、
公式によるとCAKEPHP3では

 

  • $this->Form->controll
  • $this->Form->text

 

のいずれかを利用します。

仮に使う場合、$this->Form->inputにIDが付与されなかったりと、実際に出力されるHTMLに差異が出るので注意が必要です。

 

ただ、色々とややこしいです。

 

  • $this->Form->hidden:ID定義必要
  • $this->Form->inputのtype=hidden:ID定義不要(自動付与)
  • $this->Form->templates:ID定義不要(自動付与)
  • $this->Form->select:ID定義不要(自動付与)
  • $this->Form->radio:ID定義不要(自動付与)

バージョンによって急に仕様が変わったりしそうなので入れておいた方が良さそうですね・・・。

 

Contloller系

beforeFilter

『beforeFilter』を使う時、Controllerに定義が必要です。

 

実装例

use Cake\Event\Event;

 

public function beforeFilter(Event $event) {
    parent::beforeFilter($event);
}

 

空、NULLチェックの違い

こちらがわかり易かったです。

 

norm-nois.com

ControllerからのModel呼び出し

CakePHP2の時は

 

App::uses('HogeModel','Model/Manager');
$this->model = new HogeModel(
    $this->HogeModel
);

 

のように書いていましたが、

 

$this->model = TableRegistry::getTableLocator()->get('HogeModel');

 

のように書けばOKです。

 

find('first')

なくなったみたいで、以下のように実装するようです。

なんか一度全て取得してそうで、非常に違和感がありますが・・・w

// コントローラーやテーブルのメソッド内で
$query = $articles->find('all', [
'order' => ['Articles.created' => 'DESC']
]);
$row = $query->first();

 

参考:データの取り出しと結果セット - 3.6

 

select count(*)の実装

レスポンスの取得が気持ち悪いけど、これで良いのかな。

0件だったら何も返さないで欲しい・・・。

 

// 件数取得
$conditions = array(
'date(created) >=' => value1,
'date(created) <' => value2,
'status'         => 1
);
$group = array(
'column1',
'column2'
);
$query = $this->ModelName->find();
$query->select(['count' => $query->func()->count('*')])
->where($conditions)
->group($group);
$queryResult = $query->all()->toArray();
// 配列が1つの場合は0件の場合がある
$total = count($queryResult);
if( $total === 1 ){
$total = $queryResult[0]->count;
}

Model系 

Queryの直接実行

use Cake\Datasource\ConnectionManager;
$connection = ConnectionManager::get('default');
$results = $connection->execute('SELECT * FROM articles')->fetchAll('assoc');

Modelでの厳密な保存(saveOrFail)

ModelでSaveをする時、saveOrFailメソッドを用いることで厳密な保存が可能になる。

 

try {
$table->saveOrFail($entity);
} catch (\Cake\ORM\Exception\PersistenceFailedException $e) {
echo $e->getEntity();
}

 

参考:データの保存 - 3.6 

 

CAKEPHP2の時の『useTable』に変わる表現は?

$this->ModelName->useTable

 

CAKEPHP3でのテーブル名一覧の取得方法

一応こんな感じでテーブル一覧は取れます。

だけどModelに定義されているテーブル名の取り方が不明・・・。

$this->conn = ConnectionManager::get('default');
$this->conn->schemaCollection()->listTables()

 

CAKEPHP2の時の『model->schema』に変わる表現は?

要するにカラム名の取得です。

 

$this->ModelName->getSchema()->columns()

 

でOKです。

 

Entityについて

ここがわかりやすかったです。

qiita.com

 

デバッグ

var_dumpの中身を全て出力

ini_set('xdebug.var_display_max_children', -1);
ini_set('xdebug.var_display_max_data', -1);
ini_set('xdebug.var_display_max_depth', -1);
var_dump($query);
exit;

環境系

mcryptをDocker環境のPHP7.1に入れる

OpenSSLを使わないといけないのですが、そんなことも言っていられないので非推奨を承知の上で入れます。

 

ERROR: `/tmp/pear/temp/mcrypt/configure --with-php-config=/usr/local/bin/php-config
--with-mcrypt' failed
ERROR: Service 'web' failed to build: The command '
/bin/sh -c pecl install mcrypt-1.0.1' returned a non-zero code: 1

 

・・と思ったらエラーでこけるw

とりあえず7.1で動かす(あとで直す予定・・・。)

 

動かしてみると・・・。

Error: [LogicException] rijndael is not compatible with OpenSSL.
Use mcrypt instead. in vendor/cakephp/cakephp/src/Utility/Crypto/OpenSsl.php on line 44

 

あれ、何故か動かん。

調べてみると、OpenSSLが優先されてしまうようで、config/bootstrap.phpに追記が必要みたいです。

 

// In config/bootstrap.php
use Cake\Utility\Crypto\Mcrypt;

Security::engine(new Mcrypt());

 

参考:セキュリティユーティリティ - 3.6

 

と、次はこんなエラー。

Notice Error: Use of undefined constant MCRYPT_RIJNDAEL_256
- assumed 'MCRYPT_RIJNDAEL_256'

 

mcryptがそもそも入っていなかった模様

 

最終的なDockerFileは以下。

 

FROM php:7.1-apache
ADD ./httpd.conf /etc/apache2/apache2.conf
# mod_rewrite実行
RUN a2enmod rewrite
RUN apt-get update \
&& apt-get install -y libicu-dev libxml2-dev libmcrypt-dev git vim \
&& docker-php-ext-install pdo_mysql mysqli mbstring intl simplexml mcrypt
# log用ディレクトリ作成
RUN mkdir -p /var/log/hss2
RUN chmod 777 /var/log/hss2
COPY php.ini /usr/local/etc/php/
RUN pecl install xdebug-2.6.1 && docker-php-ext-enable xdebug \
&& echo "zend_extension=$(find /usr/local/lib/php/extensions/ -name xdebug.so)" >
/usr/local/etc/php/conf.d/xdebug.ini;

 

Consoleの中に入り、phpコマンドでGrepしてみて結果が返って来ればOK。

 

root@d42437a88f29:/var/www/html# php -i | grep mcrypt
Cannot load Xdebug - it was already loaded
/usr/local/etc/php/conf.d/docker-php-ext-mcrypt.ini,
Registered Stream Filters => zlib.*, convert.iconv.*, string.rot13, string.toupper,
string.tolower, string.strip_tags, convert.*, consumed, dechunk, mcrypt.*, mdecrypt.*
mcrypt support => enabled
mcrypt_filter support => enabled
mcrypt.algorithms_dir => no value => no value
mcrypt.modes_dir => no value => no value

 

リダイレクトの謎(『?redirect=%2F』) 

PHPフレームワーク CakePHP 3入門

PHPフレームワーク CakePHP 3入門