ページ

2017年8月20日日曜日

Mac Sierraでapache +PHP5.6をPHP7.1を利用する手順

PHP5.6=>PHP7.1をMac Sierraで利用するための手順


名称概要
実行日2017/08/20
OSMacOS Sierra
Apache2.4.27
BrewHomebrew 1.3.1


$ brew tap homebrew/dupes
$ brew tap homebrew/versions
$ brew tap homebrew/php
$ brew tap homebrew/apache
$ brew update

-- 不要なら外す
$ brew unlink php56

$ brew install php71 --with-httpd24

-- 普段CakePHPをよく利用するのでついでに手順化
$ brew install php71-intl php71-pdo-pgsql

$ sudo vi /etc/apache2/httpd.conf
-- 以下の変更--
# LoadModule php5_module libexec/apache2/libphp5.so
LoadModule php7_module /usr/local/opt/php71/libexec/apache2/libphp7.so
-------------

$ sudo vi /etc/apache2/other/php7.conf
--- 以下を追加 ---

        SetHandler application/x-httpd-php


        AddType application/x-httpd-php .php
        AddType application/x-httpd-php-source .phps

        
                DirectoryIndex index.html index.php
        

---------------

sudo mv /etc/apache2/other/php5.conf /etc/apache2/other/php5.conf.bk

-- versionチェック
$ php -v

$ sudo apachectl restart

基本はこれで行けるはずですが、自分の環境では行けず以下を対応



less /var/log/apache2/error_log
---- エラーログをチェック -----
[Sun Aug 20 20:53:25.102393 2017] [mpm_prefork:notice] [pid 86] AH00163: Apache/2.4.25 (Unix) PHP/7.1.8 configured -- resuming normal operations
[Sun Aug 20 20:53:25.102609 2017] [core:notice] [pid 86] AH00094: Command line: '/usr/sbin/httpd -D FOREGROUND'
---------------------------

php.iniが古いのが問題の可能性が高い
php5.6からphp7.1向けのphp.iniを公式サイトからphp-7.1.8.tar.bz2をDLし
Downloadフォルダに解凍後以下を実施


sudo mv /etc/php.ini /etc/php.ini.20170820
sudo cp Downloads/php-7.1.8/php.ini-production /etc/php.ini

これで行けました。

localhostでWebプッシュの実現(OneSignal編)

Webプッシュ技術が流行っているので試しに実装及びまとめてみました。
環境は以下に記載ですが、localhostで試験的にやってみたい人向けに書いています。
OneSignalというサービスを利用して対応してみましたが以下の理由で対応しました。他に良いものもあるかもしれないですが自分の中ではこれが一番しっくりきました。
無料で利用できる
非SSLで利用可能
Mac & Windows系の主要ブラウザ対応(iOSは非対応)
早速検証環境を羅列
環境 概要
2017/08/19日検証
プッシュサービス OneSignal
Webサーバ macOS Sierra上にapache(Apache/2.4.25)
ホスト http://localhost/~{ユーザ名}/
基本的にMacを触っていれば初期状態?で利用できるものを前提にしてみました。
http://localhost/index.htmlに実現するイメージです。

1.サイトに登録

https://onesignal.com/
に登録、登録にはメアド&パスワードでOK
GitHubとかその他でも可
登録作業は本質ではないので省略

2.新しいプロジェクトの設定(Safari編)

2-1.プロジェクト名の入力



Add a new appを押し新規作成
ここは自分で適当に決める今回は`Test’で作成
2-2.WebSite Pushを指定


何も考えずWebSiet Pushを選択
2-3.Apple Safariを指定


まずは Safariの設定をするのでApple Safariを指定
2-4.テストサイト情報を指定


必須入力が、2つで
Site Nameこれは適当で良い今回はTest1を指定
Site URLここにhttp://localhostを指定
残り2つは製品をリリースするのなら触った方が良いがとり得ず今は放置
2-5.SDKの指定


何も考えずWebsiet Pushを選択
2-6.Test実行


この画面に来ると2つのことをする必要がある
1. 承認用HTMLの作成
2. ブラウザから承認
まずは、承認用HTMLの作成から
# sudo vi /Library/WebServer/Documents/index.html.en
以下のソースを記載
<html>
<script src="https://cdn.onesignal.com/sdks/OneSignalSDK.js" async='async'></script>
<script>
        var OneSignal = window.OneSignal || [];
        OneSignal.push(["init", {
                appId: "{Your App IDを置き換え}",
                httpPermissionRequest: {enable: true},
                allowLocalhostAsSecureOrigin: true,
                autoRegister: true,
                notifyButton: {enable: false}
        }]);
</script>
<body>
<h1>It works!</h1>
</body>
</html>
自分で、Your App IDを置き換え部分を書き換えてください。
ブラウザから承認の実行
http://localhost/
にアクセスしてアクセスを許可をしてサイトに戻り確認作業



とここまでがSafariの設定次にその他ブラウザ対応
個人的にですが実はSafariの方が簡単でした。

3.その他ブラウザ対応

次はその他ブラウザ今回のテストはChromeで実施
この方法でFireFoxも対応可能です。
3-1.設定情報の登録



App Setting => Google Chrome and Mozilla Firefox => CONFIGUREの順番で移動



入力情報がこの場合は、https://localhostにしてMy site is not fully HTTPS設定をチェックをつけないようにして登録します。
色々試したのですがこうしないと正しく登録できない。
3-2.追加ファイルの設置
ここで認証の前に一つ対応が入ります。
index.htmlの変更は不要なのですが追加でJSファイルが1つ必要です。
# cd /Library/WebServer/Documents/
# sudo wget https://cdn.onesignal.com/sdks/OneSignalSDKWorker.js
どうやらChromeやFireFoxだとローカル内のOneSignalSDKWorker.jsが必要みたいでこれを取って来る必要があります。
この内容の注意したいところがあります。
例えばサイトのアクセスがhttp://localhost/~{ユーザ名}/index.htmlこの場合でもOneSignalSDKWorker.jsのアクセス先はhttp://localhost/OneSignalSDKWorker.jsにする必要があるところです。
少しみてみるとCrhome用のデバッグコンソールに出て来るので失敗する場合は、エラーログをチェックしてみると良いです。

2017年6月24日土曜日

CakePHP クエリービルダー活用

CakePHP 3系を利用したQueryBuilderの活用法
複雑なSQL(Group BYを主体)を記載する方法を記載

基本的に、特別なケースでない場合初期化の処理は
省きController上で動作させる前提で記載します

Software Version
Postgres 9.6.1
CakePHP 3.3.16

まずはテーブルとデータを作成.
SQL

CREATE TABLE users (
 user_id SERIAL,
 user_name VARCHAR(256),
 role VARCHAR(32) DEFAULT 'author',
 created_date TIMESTAMP DEFAULT NOW(),
 update_date TIMESTAMP DEFAULT NOW(),
 PRIMARY KEY(user_id)
);

CREATE TABLE products (
 product_id SERIAL,
 product_name VARCHAR(256),
 price INTEGER,
 PRIMARY KEY(product_id)
);

CREATE TABLE product_orders (
 product_order_id SERIAL,
 product_id INTEGER,
 date TIMESAMP,
 user_id INTEGER,
 PRIMARY KEY(product_order_id)
);

データ用SQL

INSERT INTO users(user_name) VALUES
('User A'),
('User B');

INSERT INTO products(product_name, price) VALUES
('product A', 1000),
('product B', 100),
('product C', 200);

INSERT INTO product_orders(product_id, date, user_id) VALUES
(1, '2017/06/24 15:00:00', 1),
(1, '2017/06/24 16:00:00', 2),
(2, '2017/06/24 17:00:00', 3),
(1, '2017/06/25 15:00:00', 2),
(2, '2017/06/25 16:00:00', 3),
(2, '2017/06/26 15:00:00', 1);

基本的な共通処理

use Cake\ORM\TableRegistry;

public function initialize(array $config) {
    $this->Users = TableRegistry::get('Users');
    $this->Products = TableRegistry::get('Products');
    $this->ProductOrders = TableRegistry::get('ProductOrders');
}

1. 簡単なGroup BY

商品IDと合計件数を抽出

SQL

SELECT product_id, COUNT(product_order_id) AS total FROM product_orders GROUP BY product_id;

PHP

$productOrders = $this->ProductOrders->find();
$datas = $productOrders->select([
    'product_id',
    'total' => $productOrders->func()->count('product_order_id')
])->toArray();
  1. 少し複雑なGroup By
SELECT
    product_id, product_name, T1.total
FROM
    products
INNER JOIN (
    SELECT 
        product_id, COUNT(product_order_id) AS total
    FROM
        product_orders
    WHERE
        date >= '2016/06/25'
    GROUP BY product_order_id
) AS T1 USING(product_id)

PHP

$products = $this->Products->find();
$productOrders = $this->ProductOrders->find();
$datas = $productOrders->select([
    'product_id',
    'total' => $productOrders->func()->count('product_order_id')->where(['date' => new Time('2017-06-25')])
]);

$productsRecored = $products->join([
    'T1' => [
        'table' => $datas,
        'type' => 'INNER',
        'conditions' => 'T1.product_id = Products.product_id',
    ]
])->select([
    "product_id",
    "product_name",
    "total" => "T1.total"
])->toArray();

自分が困ったSQLを記載