CakePHPのControllerやRouteの書き方

/src/Model/Table/PostsTable.php

namespace App\Model\Table;

use Cake\ORM\Table;

class PostsTable extends Table
{
	public function initialize(array $config) : void {
		$this->addBehavior('Timestamp');
	}
}

/templates/Posts/index.php
L 拡張子はctpではなくphpにする
https://book.cakephp.org/4/ja/views.html

<h1>Blog Posts</h1>

<ul>
	<?php foreach($posts as $post) : ?>
		<li><?= h($post->title); ?></li>
	<?php endforeach;?>
</ul>

/src/Controller/PostsController.php

// /posts/index
// /(controller)/(action)/(options)

namespace App\Controller;

class PostsController extends AppController{

	public function index(){
		$posts = $this->Posts->find('all');
		$this->set('posts', $posts);
	}
}

config/routes.php

    $builder->connect('/', ['controller' => 'Posts', 'action' => 'index']);

controller

$posts = $this->Posts->find('all')->order(['title'=>'DESC'])->limit(2)->where(['title like'=> '%3']);

3系と4系だと、大分書き方が変わってるな。特にctpからphpに変わってるのは驚きだな。

CakePHPの環境構築

$ php -i | grep intl
$ sudo yum -y install php-intl
$ sudo vi /etc/php.d/intl.ini

extension=intl.so

$ php -i | grep intl
PHP Warning: Module ‘intl’ already loaded in Unknown on line 0
/etc/php.d/20-intl.ini,
/etc/php.d/intl.ini
intl
intl.default_locale => no value => no value
intl.error_level => 0 => 0
intl.use_exceptions => 0 => 0

### mysql
create database cakephp;
use cakephp;
create table posts (
id int unsigned auto_increment primary key,
title varchar(255),
body text,
created datetime default null,
modified datetime default null
);

insert into posts (title, body, created) values
(‘title 1’, ‘body 1’, now()),
(‘title 2’, ‘body 2’, now()),
(‘title 3’, ‘body 3’, now());

select * from posts;

### cake install
$ composer create-project –prefer-dist cakephp/app myapp

config/app_local.php

            'username' => 'root',
            'password' => 'hoge',

            'database' => 'cakephp',

config/app.php

        'defaultLocale' => env('APP_DEFAULT_LOCALE', 'ja_JP'),
        'defaultTimezone' => env('APP_DEFAULT_TIMEZONE', 'Asia/Tokyo'),

$ bin/cake bake all posts
$ bin/cake server -H 192.168.33.10 -p 8000
http://192.168.33.10:8000/posts

あああああああああ、ちょっと思い出してきたー

さくら共有サーバー cake3.5インストール後の.htaccessの設定

www/cake/に testというappを作っています。
それぞれのhtaccessのRewriteBaseでカレントディレクトリを指定してあげます。

/cake/.htaccess

  
   RewriteEngine on  
   RewriteRule    ^$ test/webroot/    [L]  
   RewriteRule    (.*) app/webroot/$1 [L]  
   RewriteBase /  
  

/cake/test/.htaccess

  
    RewriteEngine on  
    RewriteRule    ^$    webroot/    [L]  
    RewriteRule    (.*) webroot/$1    [L]  
    RewriteBase /test
  

/cake/test/webroot/.htaccess


    RewriteEngine On
    RewriteBase /test/webroot
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]

きたー

ここまでもってくるの、結構煩雑だな~
VPSの方が簡単にセットアップできるという謎現象ですね。

さくらサーバーでintlを入れた後にcakephp3.5エラー

intlも入ったし、さあ、確認とおもったら、

php composer.phar create-project --prefer-dist cakephp/app myapp

Problem 1
– cakephp/cakephp 3.5.9 requires ext-intl * -> the requested PHP extension intl is missing from your system.

これはがっかりしますね。
確かに、php -i | grep intlで何も表示されない。

原因は、この php.ini は/usr/local/php/5.6/lib/php.iniの方を読み込んでいるから。
コントロールパネルで設定したphp.iniの方は、

php -c /home/[username]/www/php.ini -i | grep intl 

で表示される。

というわけで、cake3.5を入れる際も、以下のように打ちます。

php -c /home/[username]/www/php.ini composer.phar create-project --prefer-dist cakephp/app test

こんどは上手くいってるようです。

さくら共有サーバーにintlを入れて、cakephp3.5をインストール

intlがないと動きません。
というこで、まずicuライブラリを入れます。ここはサクサクいきます。

$ cd ~/local/src
$ wget http://download.icu-project.org/files/icu4c/54.1/icu4c-54_1-src.tgz
$ tar zxvf icu4c-54_1-src.tgz
$ cd icu/source
$ ./configure --prefix=$HOME/local
$ gmake
$ gmake install

続いて、intl

$ cd ~/local/src
$ wget http://pecl.php.net/get/intl-3.0.0.tgz
$ tar zxvf intl-3.0.0.tgz
$ cd intl-3.0.0
$ phpize

次に、.configureをしますが、phpのバージョンを指定します。
/php/5.6/
ここでphpのバージョンを指定しないと、エラーになりました。

$ ./configure --prefix=$HOME/local --with-icu-dir=$HOME/local --with-php-config=/usr/local/php/5.6/bin/php-config
$ make

あとは、php.initでextensionのパスを通します。
phpinfo()に入ってることを確認。

バージョン指定のところ、毎回見落とすんだよな~
自暴自棄です。

centos php7.0.27にintlを入れようとして嵌ったこと

まず、intlを入れようとします。

# sudo yum install --enablerepo=remi --enablerepo=remi-php56 -y php-intl

すると、phpが7.0.27とエラー表示されます。

Error: Package: php-intl-5.6.34-1.el6.remi.x86_64 (remi-php56)
           Requires: php-common(x86-64) = 5.6.34-1.el6.remi
           Installed: php-common-7.0.27-1.el6.remi.x86_64 (@remi-php70)
               php-common(x86-64) = 7.0.27-1.el6.remi
           Available: php-common-5.3.3-49.el6.x86_

phpのバージョン確認

# php -v
PHP 7.0.27 (cli) (built: Jan  2 2018 12:12:41) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies

intlのリストを表示

# yum list | grep intl
intltool.noarch                            0.41.0-1.1.el6              @anaconda       -CentOS-201703281317.x86_64/6.9
perl-libintl.x86_64                        1.20-1.el6                  base
php-intl.x86_64                            5.3.3-49.el6                base
php-symfony-intl.noarch                    2.3.42-1.el6                epel
php54-php-intl.x86_64                      5.4.45-14.el6.remi          remi-safe
php55-php-intl.x86_64                      5.5.38-8.el6.remi           remi-safe
php56-php-intl.x86_64                      5.6.34-1.el6.remi           remi-safe
php70-php-intl.x86_64                      7.0.28-1.el6.remi           remi-safe
php71-php-intl.x86_64                      7.1.15-1.el6.remi           remi-safe
php72-php-intl.x86_64                      7.2.3-1.el6.remi            remi-safe

php70-php-intl.x86_64 を入れます。

# sudo yum install php70-php-intl

はいったか確認します。

# php -i | grep intl
#

なに!? 入ってない。
/opt/remi/php70/root/usr/lib64/php/modules/ に入っている。

/usr/lib64/php/modules にintl.soを入れる。

phpinfo()

コマンドライン

# php -i | grep intl
intl
intl.default_locale => no value => no value
intl.error_level => 0 => 0
intl.use_exceptions => 0 => 0

ふー焦った。

optはアドオンアプリケーションソフトウェアパッケージ(追加アプリケーション)
remiサードパーティのリポジトリの一つ とのこと。

震度に応じて、google mapのアイコン表示を変える

DBから呼び出したmagnitudeの強弱に応じて、markerのiconをgetCircle関数で呼び込んで変えます。

var map;
var infoWindow = [];
var marker = [];

var place = JSON.parse('<?php echo $place_list; ?>');
var mag = JSON.parse('<?php echo $mag_list; ?>');
var lat = JSON.parse('<?php echo $lat_list; ?>');
var lng = JSON.parse('<?php echo $lng_list; ?>');

function initMap() {
    var mapLatLng = new google.maps.LatLng({lat: 35.681167, lng: 139.767052}); 
    map = new google.maps.Map(document.getElementById('map'), { 
     center: mapLatLng, 
      zoom: 2
   });

	 for (var i = 0; i < lat.length; i++) {
	        markerLatLng = new google.maps.LatLng({lat: lat&#91;i&#93;, lng: lng&#91;i&#93;});
	        marker&#91;i&#93; = new google.maps.Marker({ 
	         position: markerLatLng, 
	            map: map,
	            icon: getCircle(mag&#91;i&#93;)
	       });
	 
	     infoWindow&#91;i&#93; = new google.maps.InfoWindow({ 
	         content: '<div class="map">' + place[i] + ' マグニチュード:' + mag[i] + '</div>' 
	       });
	     
	     markerEvent(i);
	 }

	 function getCircle(magnitude) {
        return {
          path: google.maps.SymbolPath.CIRCLE,
          fillColor: 'red',
          fillOpacity: .2,
          scale: Math.pow(2, magnitude) / 2,
          strokeColor: 'white',
          strokeWeight: .5
        };
      }
	 
	function markerEvent(i) {
	    marker[i].addListener('click', function() {
	      infoWindow[i].open(map, marker[i]);
	  });
	}
 }

おお、改めてこれは感動した。

気温が0°C以下の場合は、tickを0以下にする

php側

$temp_max = max($temp) + 0.5;
  if(min($temp) > 0 ){
   $temp_min = 0;
  } else {
   $temp_min = min($temp) - 0.5;
  }

JS側

ticks: {
            max: <?php echo $temp_max; ?>,
            min: <?php echo $temp_min; ?>,
            stepSize: 2.0
          }

最高気温の方も必要でした(モスクワ笑)

if(max($temp) < 0 ){
	 $temp_max = 0;
	} else {
	 $temp_max = max($temp) + 0.5;
	}
	if(min($temp) > 0 ){
	 $temp_min = 0;
	} else {
	 $temp_min = min($temp) - 0.5;
	}