m_shige1979のときどきITブログ

プログラムの勉強をしながら学習したことや経験したことをぼそぼそと書いていきます

Github(変なおっさんの顔でるので気をつけてね)

https://github.com/mshige1979

cakephp3でfinderでログイン条件を追加

cakephp3になってからというか少しずつ変化しているものがあります

認証処理とかも…

環境

CensOS7.x
php 7.0.3
cakephp3.2.3

認証処理で条件を付ける際にfinderを使う

以前は"scope"がありましたがそれとは別に"finder"というものがあります。
Usersテーブルとは別にテーブルのチェックなどが必要な場合はこちらがあると便利な感じ

実装

AppController

src/Controller/AppController.php

<?php
namespace App\Controller;

use Cake\Controller\Controller;
use Cake\Event\Event;

class AppController extends Controller
{

    public function initialize()
    {
        parent::initialize();

        $this->loadComponent('RequestHandler');
        $this->loadComponent('Flash');

        // 認証コンポーネント
        $this->loadComponent('Auth', [
            // ログイン後のリダイレクト
            'loginRedirect' => [
                'controller' => 'Posts',
                'action' => 'index'
            ],
            // ログアウト後のリダイレクト
            'logoutRedirect' => [
                'controller' => 'Users',
                'action' => 'login',
            ],
            // 認証
            'authenticate' => [
                // フォーム認証
                'Form' => [
                    // 暗号化
                    'passwordHasher' => [
                        'className' => 'Default',
                    ],
                    // 認証フィールド
                    'fields' => [
                        'username' => 'username',
                        'password' => 'password'
                    ],
                    // モデル
                    'userModel' => 'Users',
                    // 抽出メソッド
                    'finder' => 'login'
                ]
            ],
            // データ保存
            'storage' => 'Session',

            // 権限
            // isAuthorizedメソッドを実装する必要がある
            'authorize' => ['Controller'],
        ]);
    }

    /**
     * アクション前処理
     * @param Event $event
     */
    public function beforeFilter(Event $event)
    {
        parent::beforeFilter($event);
    }

    /**
     * Before render callback.
     *
     * @param \Cake\Event\Event $event The beforeRender event.
     * @return void
     */
    public function beforeRender(Event $event)
    {
        if (!array_key_exists('_serialize', $this->viewVars) &&
            in_array($this->response->type(), ['application/json', 'application/xml'])
        ) {
            $this->set('_serialize', true);
        }
    }

    /**
     * 認証権限判定処理
     *
     * @param $user
     * @return bool
     */
    public function isAuthorized($user)
    {
        // ユーザーの権限が"admin"の場合は全てを許可する
        if (isset($user['role']) && $user['role'] === 'admin') {
            return true;
        }

        // Default deny
        return false;
    }
}

※finderという項目に"login"を指定します。省略時は"all"

UsersTable.php

src/Model/Table/UsersTable.php

<?php
namespace App\Model\Table;

use App\Model\Entity\User;
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;

/**
 * Users Model
 *
 */
class UsersTable extends Table
{

    /**
     * Initialize method
     *
     * @param array $config The configuration for the Table.
     * @return void
     */
    public function initialize(array $config)
    {
        parent::initialize($config);

        $this->table('users');
        $this->displayField('id');
        $this->primaryKey('id');

        $this->addBehavior('Timestamp');
    }

    /**
     * ログイン用メソッド
     *
     * 独自のfindメソッド
     * @param Query $query
     * @param array $options
     * @return Query
     */
    public function findLogin(Query $query, array $options){
        // 条件を付与
        $query->where([
            'Users.status' => 0,
            'Users.deleted' => 0
        ]);
        return $query;
    }

}

SQLのログ

SELECT 
    Users.id AS `Users__id`, 
    Users.username AS `Users__username`, 
    Users.password AS `Users__password`, 
    Users.role AS `Users__role`, 
    Users.status AS `Users__status`, 
    Users.deleted AS `Users__deleted`, 
    Users.created AS `Users__created`, 
    Users.modified AS `Users__modified` 
FROM 
    users Users 
WHERE 
    (
        Users.username = 'test01' 
        AND Users.status = 0 
        AND Users.deleted = 0
    ) 
LIMIT 1

所感

HTMLのヘルパーって使いたくない…
生成されるまでどんな形かわからないんですよ…
多少手間がかかってもHTMLで書くべきかと思います…

なんでHTMLヘルパーってあるんだろう…

cakephp3でカスタムバリデーションプロバイダを作成

バリデーションのルールはチェックはいろいろありますが

多少細かいチェックなどがあった場合は対応できません。
各テーブルだけの機能ならともかくいろいろなテーブルクラスで使用する場合はバリデーションを使いまわしたい

環境

CentOS 7.x
php7.0.3
cakephp3.2.3

日本語のマニュアルがあると調査も捗る…少し放置していた隙に3.2行っていたのか…

対応

ディレクトリを作成
mkdir -p src/Model/Validation
バリデーションインターフェースを実装

src/Model/Validation/CustomValidationInterface.php

<?php
namespace App\Model\Validation;


interface CustomValidationInterface
{
    // チェックメソッドを定義する
    public static function sampleCheck1($string);

    // チェックメソッドを定義する
    public static function sampleCheck2($string, $len);
}
チェック処理を実装

src/Model/Validation/CustomValidation.php

<?php
namespace App\Model\Validation;

use Cake\Validation;

class CustomValidation implements CustomValidationInterface
{
    // チェックメソッドを実装する
    public static function sampleCheck1($check)
    {
        $result = null;
        if ($check == "check1") {
            $result = true;
        } else {
            $result = false;
        }
        return $result;
    }

    // チェックメソッドを実装する
    public static function sampleCheck2($check, $len)
    {
        $result = null;
        if ($check == "1234567890" && strlen($check) == $len) {
            $result = true;
        } else {
            $result = false;
        }
        return $result;
    }
}

※サンプルって手抜きの方がわかりやすいと思います

テーブルのバリデーションに実装
<?php
namespace App\Model\Table;

use App\Model\Entity\Post;
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
use App\Model\Validation;

/**
 * Posts Model
 *
 */
class PostsTable extends Table
{

    /**
     * Initialize method
     *
     * @param array $config The configuration for the Table.
     * @return void
     */
    public function initialize(array $config)
    {
        parent::initialize($config);

        $this->table('posts');
        $this->displayField('title');
        $this->primaryKey('id');

        $this->addBehavior('Timestamp');
    }

    /**
     * Default validation rules.
     *
     * @param \Cake\Validation\Validator $validator Validator instance.
     * @return \Cake\Validation\Validator
     */
    public function validationDefault(Validator $validator)
    {

        // プロバイダを追加
        $validator->provider('custom', Validation\CustomValidation::class);

        $validator
            ->integer('id')
            ->allowEmpty('id', 'create');

        $validator
            ->requirePresence('title', 'create')
            ->notEmpty('title')
            ->add("title", [
                "check1" => [
                    "rule" => ["sampleCheck2", 10],
                    "message" => "カスタムプロバイダーエラー1",
                    "provider" => "custom",  // 使用するプロバイダ名を設定
                ]
            ]);

        $validator
            ->requirePresence('body', 'create')
            ->notEmpty('body');

        return $validator;
    }

}

こんな感じ

所感

cakephp2の場合はビヘイビアに組み込むという方法で共通化していたので別の場所に配置できるようになるとメンテナンスもやりやすくなるかも…
データだけのチェックの場合とデータベースが絡む場合で難易度が変わるかもしれないので注意する必要があるかもしれないけど…

CentOS6.xにphp7のインストールテスト

せっかくなのでvmを作成してインストールしてみる(準備)

git clone https://github.com/mshige1979/vagrant-centos-dev-001.git -b test00 test02
cd test02
vagrant up
vagrant ssh
yum
sudo yum -y install gcc gcc-c++ git wget tar m4 autoconf httpd vim
sudo yum -y install httpd-devel gd-devel libxml2-devel mysql-devel t1lib-devel
sudo yum -y install bzip2-devel curl-devel gmp-devel aspell-devel recode-devel
sudo yum -y install icu libicu-devel
sudo yum -y install php-intl
phpをダウンロードしてからビルド
wget https://github.com/php/php-src/archive/php-7.0.0RC1.tar.gz
tar zxf php-7.0.0RC1.tar.gz
cd php-src-php-7.0.0RC1/
./buildconf --force
./configure \
    --prefix=/usr/local/php \
    --with-config-file-path=/usr/local/php/etc \
    --enable-mbstring \
    --enable-zip \
    --enable-bcmath \
    --enable-pcntl \
    --enable-ftp \
    --enable-exif \
    --enable-intl \
    --enable-calendar \
    --enable-sysvmsg \
    --enable-sysvsem \
    --enable-sysvshm \
    --enable-wddx \
    --with-curl \
    --with-mcrypt \
    --with-iconv \
    --with-gmp \
    --with-pspell \
    --with-gd \
    --with-jpeg-dir=/usr \
    --with-png-dir=/usr \
    --with-zlib-dir=/usr \
    --with-xpm-dir=/usr \
    --with-freetype-dir=/usr \
    --enable-gd-native-ttf \
    --enable-gd-jis-conv \
    --with-openssl \
    --with-pdo-mysql=/usr \
    --with-gettext=/usr \
    --with-zlib=/usr \
    --with-bz2=/usr \
    --with-recode=/usr \
    --with-mysqli=/usr/bin/mysql_config \
    --with-apxs2=/usr/sbin/apxs
make && make test
sudo make insall

$ sudo make install
Installing PHP SAPI module:       apache2handler
/usr/lib64/httpd/build/instdso.sh SH_LIBTOOL='/usr/lib64/apr-1/build/libtool' libphp7.la /usr/lib64/httpd/modules
/usr/lib64/apr-1/build/libtool --mode=install cp libphp7.la /usr/lib64/httpd/modules/
libtool: install: cp .libs/libphp7.so /usr/lib64/httpd/modules/libphp7.so
libtool: install: cp .libs/libphp7.lai /usr/lib64/httpd/modules/libphp7.la
libtool: install: warning: remember to run `libtool --finish /home/vagrant/php-src-php-7.0.0RC1/libs'
chmod 755 /usr/lib64/httpd/modules/libphp7.so
[activating module `php7' in /etc/httpd/conf/httpd.conf]
Installing shared extensions:     /usr/local/php/lib/php/extensions/no-debug-non-zts-20141001/
Installing PHP CLI binary:        /usr/local/php/bin/
Installing PHP CLI man page:      /usr/local/php/php/man/man1/
Installing phpdbg binary:         /usr/local/php/bin/
Installing phpdbg man page:       /usr/local/php/php/man/man1/
Installing PHP CGI binary:        /usr/local/php/bin/
Installing PHP CGI man page:      /usr/local/php/php/man/man1/
Installing build environment:     /usr/local/php/lib/php/build/
Installing header files:          /usr/local/php/include/php/
Installing helper programs:       /usr/local/php/bin/
  program: phpize
  program: php-config
Installing man pages:             /usr/local/php/php/man/man1/
  page: phpize.1
  page: php-config.1
Installing PEAR environment:      /usr/local/php/lib/php/
--2015-08-23 14:13:15--  https://pear.php.net/~cweiske/1.10.0dev2/install-pear-nozlib.phar
pear.php.net をDNSに問いあわせています... 5.77.39.20
pear.php.net|5.77.39.20|:443 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 3572266 (3.4M) [text/plain]
`pear/install-pear-nozlib.phar' に保存中

100%[==================================================================================================================>] 3,572,266    177K/s 時間 39s

2015-08-23 14:14:01 (89.2 KB/s) - `pear/install-pear-nozlib.phar' へ保存完了 [3572266/3572266]

[PEAR] Archive_Tar    - installed: 1.4.0
[PEAR] Console_Getopt - installed: 1.4.1
[PEAR] Structures_Graph- installed: 1.1.1
[PEAR] XML_Util       - installed: 1.3.0
[PEAR] PEAR           - installed: 1.10.0dev2
Wrote PEAR system config file at: /usr/local/php/etc/pear.conf
You may want to add: /usr/local/php/lib/php to your php.ini include_path
/home/vagrant/php-src-php-7.0.0RC1/build/shtool install -c ext/phar/phar.phar /usr/local/php/bin
ln -s -f phar.phar /usr/local/php/bin/phar
Installing PDO headers:          /usr/local/php/include/php/ext/pdo/
$
設定ファイルをコピーして、環境変数に追加
sudo cp -p php.ini-development /usr/local/php/etc/php.ini
echo 'export PATH=$PATH:/usr/local/php/bin' >> ~/.bash_profile
source ~/.bash_profile
実行
$ php -v
PHP 7.0.0RC1 (cli) (built: Aug 23 2015 13:55:47)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v3.0.0-dev, Copyright (c) 1998-2015 Zend Technologies
$

phpinfo

info.php
<?php
        phpinfo();
起動
php -S 192.168.33.10:1234
結果

f:id:m_shige1979:20150823233020p:plain

cakephp3

mysql
mysql -u root -e "create database my_app default charset utf8"
mysql -u root -e "create database test_my_app default charset utf8"
mysql -u root -e "GRANT ALL PRIVILEGES ON *.* TO 'my_app'@'localhost' IDENTIFIED BY 'secret' WITH GRANT OPTION;"
install
curl -s https://getcomposer.org/installer | php
php composer.phar create-project --prefer-dist cakephp/app app1
app1/
bin/cake server -H 192.168.33.10 -p 1234

f:id:m_shige1979:20150824002632p:plain

所感

なんとかcakephp3も初期ページまでは動くようです。拡張モジュールなどを利用している場合はうまく有効にしているかを
確認しないと動かせないことがあるのでインストール時などに注意を行うことが必要と思われる。
php7の新機能はまた今度確認する

cakephp3の学習(ルーティング)

BookMakerのチュートリアルの一部

きちんと理解しないとソースコピーじゃ動かん

これを見てから学習していく

Bookmarker Tutorial — CakePHP Cookbook 3.x documentation

今回はこれ

config/routes.php

Router::scope(
    '/bookmarks',
    ['controller' => 'Bookmarks'],
    function ($routes) {
        $routes->connect('/tagged/*', ['action' => 'tags']);
    }
);


いままでの知識より考えると
/bookmarks
以下のURLにタグ文字を設定していくことでブックマーク用のタグをURLで設定できる

その処理をactionに設定できる

コントローラーに設定

src/Controller/BookmarksController.php

public function tags(){
        $tags = $this->request->params['pass'];
        /*
        $bookmarks = $this->Bookmarks->find('tagged', [
            'tags' => $tags
        ]);
        */
        var_dump($tags);

    }

※モデルの部分は無視するよ(^^)
※ここで「$this->request->params['pass'];」これでpassパラメータを配列で取得できるよ

で実験

f:id:m_shige1979:20150223201635p:plain

この方法をとることでタグを保有するブックマークリストを取得できるはず

cakephp3でモデル(find+xxxx)任意のfindメソッドを準備する

モデルでデータを取得する場合はfindメソッドを使用することが多いと思う

<?php
namespace App\Shell;

use Cake\Console\Shell;
use Cake\ORM\TableRegistry;

/**
 * Sample1 shell command.
 */
class Sample1Shell extends Shell
{

    /**
     * main() method.
     *
     * @return bool|int Success or error code.
     */
    public function main() {

        // table
        $bookmarks = TableRegistry::get('bookmarks');

        // find
        $query = $bookmarks
            ->find()
            ->contain(['users']);

        // SQ
        print_r($query->sql());
        print_r("\n");

    }
}

※findメソッドにいろいろな条件を付与して様々な結果を取得するけど

ある程度まとめたい

毎回findに条件を付与するより、可変パラメータだけを渡したいな〜

find+任意の名前でメソッドを作成

サンプル

<?php
namespace App\Model\Table;

use App\Model\Entity\Bookmark;
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;

/**
 * Bookmarks Model
 */
class BookmarksTable extends Table
{

    /**
     * Initialize method
     *
     * @param array $config The configuration for the Table.
     * @return void
     */
    public function initialize(array $config)
    {
        $this->table('bookmarks');
        $this->displayField('title');
        $this->primaryKey('id');
        $this->addBehavior('Timestamp');
        $this->belongsTo('Users', [
            'foreignKey' => 'user_id'
        ]);
        $this->belongsToMany('Tags', [
            'foreignKey' => 'bookmark_id',
            'targetForeignKey' => 'tag_id',
            'joinTable' => 'bookmarks_tags'
        ]);
    }

    /**
     * Default validation rules.
     *
     * @param \Cake\Validation\Validator $validator Validator instance.
     * @return \Cake\Validation\Validator
     */
    public function validationDefault(Validator $validator)
    {
        $validator
            ->add('id', 'valid', ['rule' => 'numeric'])
            ->allowEmpty('id', 'create')
            ->add('user_id', 'valid', ['rule' => 'numeric'])
            ->requirePresence('user_id', 'create')
            ->notEmpty('user_id')
            ->allowEmpty('title')
            ->allowEmpty('description')
            ->allowEmpty('url');

        return $validator;
    }

    /**
     * Returns a rules checker object that will be used for validating
     * application integrity.
     *
     * @param \Cake\ORM\RulesChecker $rules The rules object to be modified.
     * @return \Cake\ORM\RulesChecker
     */
    public function buildRules(RulesChecker $rules)
    {
        $rules->add($rules->existsIn(['user_id'], 'Users'));
        return $rules;
    }


    // これです
    public function findTagged(Query $query, array $options){
        return 
            $this
                ->find()
                ->matching('Tags', function ($q) use ($options) {
                    return $q->where(['Tags.title IN' => $options['tags']]);
                });
    }
}

※Tableのクラスに追加

それで、Tableのクラスを使用するところでfind以降のメソッド名を指定

<?php
namespace App\Shell;

use Cake\Console\Shell;
use Cake\ORM\TableRegistry;

/**
 * Sample2 shell command.
 */
class Sample2Shell extends Shell
{

    /**
     * main() method.
     *
     * @return bool|int Success or error code.
     */
    public function main() {

        // table
        $bookmarks = TableRegistry::get('bookmarks');

        // find
        $query =  $bookmarks->find('tagged', [
            'tags' => ['111', '222']
        ]);

        // SQ
        print_r($query->sql());
        print_r("\n");

    }
}

※第1引数のパラメータで"find"以降のメソッド名を指定する
こうすることで取得できる
戻り値はまあ好きに対応することが可能と思います

結果

SELECT 
  bookmarks.id AS `bookmarks__id`
  , bookmarks.user_id AS `bookmarks__user_id`
  , bookmarks.title AS `bookmarks__title`
  , bookmarks.description AS `bookmarks__description`
  , bookmarks.url AS `bookmarks__url`
  , bookmarks.created AS `bookmarks__created`
  , bookmarks.updated AS `bookmarks__updated`
  , Tags.id AS `Tags__id`
  , Tags.title AS `Tags__title`
  , Tags.created AS `Tags__created`
  , Tags.updated AS `Tags__updated`
  , BookmarksTags.bookmark_id AS `BookmarksTags__bookmark_id`
  , BookmarksTags.tag_id AS `BookmarksTags__tag_id` 

FROM 
  bookmarks bookmarks 
  INNER JOIN tags Tags ON 
    Tags.title in (:c0,:c1) 
    
  INNER JOIN bookmarks_tags BookmarksTags ON 
      (
        bookmarks.id = (BookmarksTags.bookmark_id) 
        AND Tags.id = (BookmarksTags.tag_id)
      )

所感

チュートリアルをやっていきながら不明な場所を解決して理解を進めていくようにします

cakephp3でjsonとかxmlとかを使う

jsonを使ったデータを使ってみたいけどなんかうまくいかない

英語のマニュアルを見て頑張った

バージョン

cakephp3.0.8

実装

config/routes.php
<?php
/**
 * Routes configuration
 *
 * In this file, you set up routes to your controllers and their actions.
 * Routes are very important mechanism that allows you to freely connect
 * different URLs to chosen controllers and their actions (functions).
 *
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 * @link          http://cakephp.org CakePHP(tm) Project
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
 */

use Cake\Core\Plugin;
use Cake\Routing\Router;

/**
 * The default class to use for all routes
 *
 * The following route classes are supplied with CakePHP and are appropriate
 * to set as the default:
 *
 * - Route
 * - InflectedRoute
 * - DashedRoute
 *
 * If no call is made to `Router::defaultRouteClass`, the class used is
 * `Route` (`Cake\Routing\Route\Route`)
 *
 * Note that `Route` does not do any inflections on URLs which will result in
 * inconsistently cased URLs when used with `:plugin`, `:controller` and
 * `:action` markers.
 *
 */
Router::defaultRouteClass('Route');
Router::extensions(['json', 'xml']);

Router::scope('/', function ($routes) {
    /**
     * Here, we are connecting '/' (base path) to a controller called 'Pages',
     * its action called 'display', and we pass a param to select the view file
     * to use (in this case, src/Template/Pages/home.ctp)...
     */
    $routes->connect('/', ['controller' => 'Pages', 'action' => 'display', 'home']);

    /**
     * ...and connect the rest of 'Pages' controller's URLs.
     */
    $routes->connect('/pages/*', ['controller' => 'Pages', 'action' => 'display']);

    /**
     * Connect catchall routes for all controllers.
     *
     * Using the argument `InflectedRoute`, the `fallbacks` method is a shortcut for
     *    `$routes->connect('/:controller', ['action' => 'index'], ['routeClass' => 'InflectedRoute']);`
     *    `$routes->connect('/:controller/:action/*', [], ['routeClass' => 'InflectedRoute']);`
     *
     * Any route class can be used with this method, such as:
     * - DashedRoute
     * - InflectedRoute
     * - Route
     * - Or your own route class
     *
     * You can remove these routes once you've connected the
     * routes you want in your application.
     */
    $routes->fallbacks('InflectedRoute');

});

/**
 * Load all plugin routes.  See the Plugin documentation on
 * how to customize the loading of plugin routes.
 */
Plugin::routes();

※「Router::extensions(['json', 'xml']);」を追加する

src/Controller/AppController.php
<?php
/**
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 * @link      http://cakephp.org CakePHP(tm) Project
 * @since     0.2.9
 * @license   http://www.opensource.org/licenses/mit-license.php MIT License
 */
namespace App\Controller;

use Cake\Controller\Controller;

/**
 * Application Controller
 *
 * Add your application-wide methods in the class below, your controllers
 * will inherit them.
 *
 * @link http://book.cakephp.org/3.0/en/controllers.html#the-app-controller
 */
class AppController extends Controller
{

    /**
     * Initialization hook method.
     *
     * Use this method to add common initialization code like loading components.
     *
     * @return void
     */
    public function initialize()
    {
        parent::initialize();
        $this->loadComponent('Flash');
        $this->loadComponent('RequestHandler');

    }

}

※「$this->loadComponent('RequestHandler');」を追加
※AppControllerでなくても各コントローラーのinitializeに実装すればよい

独自のコントローラー
<?php
/**
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 * @link      http://cakephp.org CakePHP(tm) Project
 * @since     0.2.9
 * @license   http://www.opensource.org/licenses/mit-license.php MIT License
 */
namespace App\Controller;

use Cake\Core\Configure;
use Cake\Network\Exception\NotFoundException;
use Cake\View\Exception\MissingTemplateException;

/**
 * Static content controller
 *
 * This controller will render views from Template/Pages/
 *
 * @link http://book.cakephp.org/3.0/en/controllers/pages-controller.html
 */
class SamplesController extends AppController
{

    public function test(){

        $data = [
            "aaa" => [111, 222, 333],
            "bbb" => [
                "ccc1" => 10,
                "ccc2" => [
                    "aaa",
                    "bbb",
                    "ccc",
                ],
            ],
        ];

        $this->set([
            'data' => $data,
            '_serialize' => ['data']
        ]);
    }

}

jsonを意識しているのでこんな感じのショボイデータ

実行

xml

f:id:m_shige1979:20150704141436p:plain

XMLでアブソリュート?とかきちんとしたい場合は別の方法で送信したほうがいいかも…

このへんは重要

  1. Router::extensions(['json', 'xml']);
  2. $this->loadComponent('RequestHandler');
  3. Templateディレクトリにビューファイルを作成しなくても良い

所感

メソッド結構変わっているので戸惑いを隠せない
ある程度は同じやつが良かった
jsonpとか動かせるかはこの際無視しよう
とりあえず、これでajaxなどでの通信を使えるようになるはず

laravel5でコントローラーを確認

単純にテキストを出力する場合やjson形式などを確認

viewを使用する場合とそうでない場合の確認

基本

サンプルアプリなので単純にコントローラーの雛形を作成して検証する

準備
php composer.phar create-project laravel/laravel sampleapp2 --prefer-dist
cd sampleapp2/
php artisan make:controller Test1sController
ルーティング
<?php

Route::get('/test1', 'Test1sController@index');

テキストをそのまま出す場合

app/Http/Controllers/Test1sController.php
<?php namespace App\Http\Controllers;

use App\Http\Requests;
use App\Http\Controllers\Controller;

use Illuminate\Http\Request;

class Test1sController extends Controller {

	/**
	 * Display a listing of the resource.
	 *
	 * @return Response
	 */
	public function index()
	{
		//
        return "aaaaaaaaaaaa";
	}



}

f:id:m_shige1979:20150510191415p:plain

json形式?

app/Http/Controllers/Test1sController.php
<?php namespace App\Http\Controllers;

use App\Http\Requests;
use App\Http\Controllers\Controller;

use Illuminate\Http\Request;

class Test1sController extends Controller {

	/**
	 * Display a listing of the resource.
	 *
	 * @return Response
	 */
	public function index()
	{
		//
        return [
            "res" => 200,
            "body" => [
                "aaa" => 10,
                "bbb" => "sssss",
                "ccc" => "sssssd"
            ],
        ];
	}



}

f:id:m_shige1979:20150510191820p:plain

viewを使用する場合

viewを作成

resources/views/test1s/index.blade.php

@extends('app')

@section('content')
    <div>aaa={{$data["aaa"]}}</div>
    <div>bbb={{$data["bbb"]}}</div>
    <div>ccc=
        @foreach($data["ccc"] as $key => $item)
            <p>{{$key}} = {{$item}}</p>
        @endforeach

    </div>
@endsection

※viewを使用する場合はlaravelの場合はblade.php拡張子でlaravel特有の記載方法があるので意識しておく

app/Http/Controllers/Test1sController.php
<?php namespace App\Http\Controllers;

use App\Http\Requests;
use App\Http\Controllers\Controller;

use Illuminate\Http\Request;

class Test1sController extends Controller {

	/**
	 * Display a listing of the resource.
	 *
	 * @return Response
	 */
	public function index()
	{

        $data = [
            "aaa" => 100,
            "bbb" => 200,
            "ccc" => [
                "xxx" => "111",
                "yyy" => "222",
            ],
        ];

		//
        return view('test1s.index')->with(compact('data'));
	}
    
}

※変数は1つにまとめた方が便利になる感じ?

f:id:m_shige1979:20150510193245p:plain
※基本的にphpが有効な記法も使用できる

所感

テキストやJSONは簡単なイメージ、XMLの方法がよく見つけられなかったので自前で用意する必要になりそう。
viewのテンプレートは少し慣れれば大丈夫かも