20200124のPHPに関する記事は10件です。

外為で勝つために その5 ~ Laravel 編

前回「外為で勝つために その4 ~ LINE 通知編」の続きです。

ご無沙汰してます。
ポータルサイトを作るための材料を用意したり、NISA で株の買い付けしたりしてました。
今年もどうぞよろしくお願いします。

ポータルサイトを作るにあたり、
チャートなどを表示するために、データベースに接続する必要があります。

データベース接続といえば PHP ですが
ここはオシャレに Laravel フレームワークを使いたいと思います。
PHP だけでも構築できますが、勉強も兼ねてということで。

PHP バージョン確認

早速問題になるのが PHP のバージョンです。
今回導入する Laravel は 6.7.0 で、土台として PHP 7.2 以上が必要なのだそう。

Raspberry Pi の標準的なインストール方法では PHP 7.0.33 までしか入りません。

$ php -v
PHP 7.0.33-0+deb9u6 (cli) (built: Oct 24 2019 18:50:20) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies
    with Zend OPcache v7.0.33-0+deb9u6, Copyright (c) 1999-2017, by Zend Technologies

PHP 7.3 をインストール

ということで、裏技的に PHP 7.3 をインストールします。(執筆時点で安定した最新版)
まずは管理者ログインして、apt に必要なキー情報を登録します。

$ sudo -i
# wget -O - https://packages.sury.org/php/apt.gpg | apt-key add -
stdout へ出力完了 [1769/1769]

パッケージリストを更新して PHP 7.3 を探せるようにします。

# echo "deb https://packages.sury.org/php/ stretch main" >> /etc/apt/sources.list.d/php.list
# apt-get update                                     
パッケージリストを読み込んでいます... 完了

インストールできる PHP のバージョンを確認します。
7.3 の文字が見えますね。

# apt-cache policy php
php:
  インストールされているバージョン: 1:7.0+49
  候補:               2:7.3+70+0~20191118.18+debian9~1.gbp66b4ed
  バージョンテーブル:
     2:7.3+70+0~20191118.18+debian9~1.gbp66b4ed 500
        500 https://packages.sury.org/php stretch/main armhf Packages
 *** 1:7.0+49 500
        500 http://raspbian.raspberrypi.org/raspbian stretch/main armhf Packages
        100 /var/lib/dpkg/status

PHP 7.3 をインストールします。バージョンは必ず指定してあげましょう。
インストールはあっけなく終わるので、管理者からログアウトしてバージョンを確認します。

# apt-get install php7.3
# exit
ログアウト
$ php -v
PHP 7.3.12-1+0~20191128.49+debian9~1.gbp24559b (cli) (built: Nov 28 2019 07:38:18) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.12, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.3.12-1+0~20191128.49+debian9~1.gbp24559b, Copyright (c) 1999-2018, by Zend Technologies

PHP 7.3.12 が無事インストールされました。

Laravel インストールの下準備

Laravel にはいくつか必要なモジュールがあるそうで、
下記のコマンドを実行して表示されないモジュールをインストールするようなことが、どこかに書いてありました。(どこだったかはもう完全に忘れました)

$ php -m | grep -e openssl -e PDO -e mbstring -e tokenizer -e ^xml$ -e ctype -e json -e bcmath
ctype
json
openssl
PDO
tokenizer

mbstringxmlbcmath がないですね。
モジュール名それぞれの先頭に php- を付けてインストールしておきます。

インストールが終わったら、同じ確認コマンドを実行して再確認します。問題なさそうですね。

$ sudo apt-get install php-bcmath php-mbstring php-xml
$ php -m | grep -e openssl -e PDO -e mbstring -e tokenizer -e ^xml$ -e ctype -e json -e bcmath
bcmath
ctype
json
mbstring
openssl
PDO
tokenizer
xml

Composer のインストール

Laravel は PHP のフレームワークでありパッケージの1つです。
PHP 関係のパッケージは Composer で依存性を一元管理するらしいです(多分)。いわゆるパッケージマネージャーですね。これを先にインストールしておきます。

それにしても、やたら味のある Web サイトのトップだったのでスクショしておきました。
良いセンスを感じますねぇ。

Screenshot_20200124[1].png

それはさておき、
インストーラを HTTP GET して、そのままインストールします。

$ curl -sS https://getcomposer.org/installer | php
All settings correct for using Composer
Downloading...

Composer (version 1.9.1) successfully installed to: /home/pi/composer.phar
Use it: php composer.phar

$ sudo mv composer.phar /usr/local/bin/composer
$ composer -v
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
Composer version 1.9.1 2019-11-01 17:20:17

インストールはあっさり完了しました。

Laravel のインストール

いよいよ本命の Laravel をインストールします。
Composer 経由でインストールコマンドを実行します。

$ cd /home/pi/.config/composer
$ composer global require laravel/installer

  Problem 1
    - laravel/installer v3.0.1 requires ext-zip * -> the requested PHP extension zip is missing from your system.
    - laravel/installer v3.0.0 requires ext-zip * -> the requested PHP extension zip is missing from your system.
    - Installation request for laravel/installer ^3.0 -> satisfiable by laravel/installer[v3.0.0, v3.0.1].

Installation failed, deleting ./composer.json.

なんか失敗しましたね。
zip が足らんのでインストールが続行できないとのこと。

ならば php-zip をインストールしてリトライ。

$ sudo apt-get install php-zip
$ composer global require laravel/installer
Changed current directory to /home/pi/.config/composer
Using version ^3.0 for laravel/installer
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 14 installs, 0 updates, 0 removals
  - Installing symfony/process (v5.0.1): Downloading (100%)
  - Installing symfony/polyfill-ctype (v1.13.1): Downloading (100%)
  - Installing symfony/filesystem (v5.0.1): Downloading (100%)
  - Installing psr/container (1.0.0): Downloading (100%)
  - Installing symfony/service-contracts (v2.0.1): Downloading (100%)
  - Installing symfony/polyfill-php73 (v1.13.1): Downloading (100%)
  - Installing symfony/polyfill-mbstring (v1.13.1): Downloading (100%)
  - Installing symfony/console (v5.0.1): Downloading (100%)
  - Installing ralouphie/getallheaders (3.0.3): Downloading (100%)
  - Installing psr/http-message (1.0.1): Downloading (100%)
  - Installing guzzlehttp/psr7 (1.6.1): Downloading (100%)
  - Installing guzzlehttp/promises (v1.3.1): Downloading (100%)
  - Installing guzzlehttp/guzzle (6.5.0): Downloading (100%)
  - Installing laravel/installer (v3.0.1): Downloading (100%)
symfony/service-contracts suggests installing symfony/service-implementation
symfony/console suggests installing symfony/event-dispatcher
symfony/console suggests installing symfony/lock
symfony/console suggests installing psr/log (For using the console logger)
guzzlehttp/psr7 suggests installing zendframework/zend-httphandlerrunner (Emit PSR-7 responses)
guzzlehttp/guzzle suggests installing psr/log (Required for using the Log middleware)
guzzlehttp/guzzle suggests installing ext-intl (Required for Internationalized Domain Name (IDN) support)
Writing lock file
Generating autoload files

インストールできた感じは微塵もありませんが、無事完了したようです。

Laravel Web Artisan の作成

もう少しです。
インストールは完了したので、Laravel 実行環境である(プロジェクトとも呼ばれる)Web Artisan(ウェブ職人)を作成します。

事前に composer/vendor/bin にパスを通しておきます。
作成先フォルダは /var/www/html/MarketMonitor にしました。
laravel new <Project Name> で作成します。今回はひねりなく laravel にしました。

$ export PATH="~/.config/composer/vendor/bin:$PATH"
$ cd /var/www/html/MarketMonitor

$ laravel new laravel
Package manifest generated successfully.
Application ready! Build something amazing.

「アプリケーションの準備ができました!素晴らしいものを作りましょう」
と言われたらインストール完了です。もちろん作りますよ。素晴らしいものを。

Laravel のテスト

「すばらっ」なアプリケーションを作成する前に、実際動くかどうかをテストしましょう。
書き込みが発生する(であろう)ディレクトリ配下のファイルに、パーミッションを与えておきます。

php artisan serve を実行するとサーバーが起動します。

$ chmod -R 777 /var/www/html/MarketMonitor/laravel/storage
$ chmod -R 777 /var/www/html/MarketMonitor/laravel/bootstrap/cache
$ cd /var/www/html/MarketMonitor/laravel
$ php artisan --version
Laravel Framework 6.7.0
$ php artisan serve
Laravel development server started: http://127.0.0.1:8000
[Wed Dec 11 14:06:27 2019] 127.0.0.1:47120 [200]: /favicon.ico

ttp://127.0.0.1:8000 にアクセスしろ、とのことです。

Screenshot_20200124[2].png

成功ですね。
これでデータベースにアクセスし放題です!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PHPStormのTemplateを設定してdeclare(strict_types=1)を常に設定する

PHPStormのTemplateを設定してdeclare(strict_types=1)を常に設定する

PHP7からdeclare(strict_types=1)が導入され、設定している場合は暗黙的な型変換が行われなくなり、より厳密にタイプヒンティングをチェックするようにできます。

しかしdeclare(strict_types=1)はファイル単位でしか効力が無いため、常にファイルの冒頭に書かなければいけません。

これを矯正するためにPHPStormに設定を追加します。

スクリーンショット 2020-01-24 18.38.47.png

PHPStormのCode Templatesを利用します。

Preferences > Editor > File and Code TemplatesでPHPを選択し、テンプレートの初めにdeclare(strict_types=1)を追記しましょう。

これでPHPファイルを作成するときに自動的にdeclare(strict_types=1)が追加されます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PHP の array_reduce 関数 分かりやいサンプル

array_reduce ( array $array , callable $callback [, mixed $initial = NULL ] ) : mixed

array_reduce() は、配列 array の各要素に callback 関数を繰り返し適用し、 配列を一つの値に減らします。

例:


<?php

function sum($carry, $item) {
    var_dump($carry, $item);
    $carry += $item;
    echo '<br><hr>';
    return $carry;
}

$a = array(1, 2, 3, 4, 5);

var_dump(array_reduce($a, 'sum', 10));

結果

int(10) int(1)
int(11) int(2)
int(13) int(3)
int(16) int(4)
int(20) int(5)
int(25)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravelでトランザクションをネストせずに新しいトランザクションを切る

毎度同じことをやろうと思った時にどうやればいいか忘れてしまうので備忘も兼ねて

はじめに

Laravelでは以下のコードのようにするとトランザクションをネストしてSAVEPOINTを作成するため、やんごとなき事情で新しいトランザクションを切りたいなーと思ってもうまくいきません。
(ID発番が連番ではない場合に別テーブルでID発番を管理しトランザクションを分けることでロックする時間を短くするとか)

    DB::beginTransaction();
    {
        DB::beginTransaction();
        Animal::create(['name' => 'ぺんぎんさん']);
        DB::commit();
    }
    DB::rollBack(); // ぺんぎんさんの挿入もロールバックされる!

SAVEPOINTってなんだ!って方は以下の記事が非常にわかりやすかったです。
●トランザクションのネストの使い方まとめた(初心者向け)
https://qiita.com/_natsu_no_yuki_/items/e1db2a132cbff740896d

実装方法

トランザクションを乱立させることはそう多くないと思うので、簡単にできる別コネクションを作成する方法を記載します。

準備

config/database.phpにデフォルトで利用している接続情報をまるっとコピーします。

database.php
        // 既存の接続情報
        'mysql' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],

        // ★mysqlの項目を丸コピした接続情報
        'mysql_2' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],

実装

新しいトランザクションを切りたい場合は、DBファサードのconnectionで追加した接続情報のキーを設定します。
Eloquentを利用する場合は、その中でModelのインスタンスを作成し、setConnectionで追加した接続情報のキーを設定します。

  • 手動トランザクションの場合
    // デフォルトのコネクションでトランザクションの開始
    DB::beginTransaction();
    {
        // 追加した接続情報をセットして、トランザクションの開始
        $mysql2 = \DB::connection('mysql_2');
        $mysql2->beginTransaction();

        // Modelのインスタンスを作成し、追加した接続情報をセットする
        $animal = new Animal();
        $animal->setConnection('mysql_2');
        $animal->create(['name' => 'ぺんぎんさん']);

        // mysql_2のコネクションをコミットする
        $mysql2->commit();
    }
    // デフォルトのコネクションをロールバックする
    DB::rollBack(); // ぺんぎんさんのデータもコミットされている!
  • トランザクションメソッドの場合
    DB::transaction(function () {
        DB::connection('mysql_2')->transaction(function () {
            $animal = new Animal();
            $animal->setConnection('mysql_2');
            $animal->create(['name' => 'ぺんぎんさん']);
        });
        throw new Exception(); // ぺんぎんさんのデータもコミットされている!
    });

おわりに

なんだかんだネストではなく、別トランザクションを切りたくなることはあるので、newTransactionとかできると嬉しいんだろうなというお気持ちでした。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

静的メソッドと動的メソッドの違い

自分なりのメモです。

ずっと前から気になってた

selfと$thisの違いってなに

ざっくりいうと

そのクラスのインスタンスが持つプロパティがメソッドの結果に
・影響を受けないのが静的メソッド
・影響を受けるのが動的メソッド

もっとわかりやすい参考

【PHP】静的と動的メソッドとは

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PHPの基礎知識整理

なんぞやについて

PHPについて

HTMLに埋め込むことができる、Web開発でよく使用されるスクリプト言語

当初の名称は「Personal Home Page Tools」
個人の履歴書を公開する為の簡易ツール

PHPとHTML・Javascriptの違い

PHP:サーバサイド動的にWebページを生成
HTML:静的にWebページの表示
JS:クライアントサイド動的にWebページを生成
→ どのようなコードが書かれているのか、誰でも見ることができる

PHPはサーバサイドであるため、サーバー側にあるMySQLなどのデータベースと連携することが可能

できること

・HTMLソースコードを生成
→ HTMLの一部分のみPHPで生成することができる(後述)
・データベースと連携
・クライアントから送信された情報を受け取る
・ファイル操作
・API連携
・バッチ処理
・WordPress[^2]のカスタマイズ

作れるもの

・お問い合わせフォーム
・予約サイト
・検索機能
・ログイン機能
・ECサイト
・SNS
・グループウェア
・社内管理システム全般

書き方

sample.php
<!DOCTYPE html>
<html>
    <head>
        <title>基本的なPHPの書き方</title>
    </head>
    <body>

        <?php
            echo "HELLO WORLD";
        ?>

     </body>
</html>

クライアントサイドでソースを確認すると、
<?php echo "HELLO WORLD"; ?>の部分はHELLO WORLDしか表示されない

また、繰り返しなどの処理もHTML内に書くことができる

sample.php
<!DOCTYPE html>
<html>
    <body>

        <?php if ($a == $b): ?>
            echo "HELLO WORLD";
        <?php else: ?>
            echo "BYE";
        <?php endif; ?>

     </body>
</html>

参考

  1. 超初心者向け!PHPでできること12選まとめました | エンジニアの入り口
  2. 今さら聞けない!PHPとは【初心者向け】 | TechAcademyマガジン
  3. PHPとは?基礎知識、できることを初心者にもわかりやすく解説します | カゴヤのサーバー研究室
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

始めてWebサイトを作成した時にお世話になった記事

初めに

プログラミングを始め、初めてWebサイトを作成した時に自分がお世話になった記事をここにあげます。
もし自分と同じようなところで悩んでいるところがあれば、参考にしていってください。

参考にした記事一覧

環境構築編
WindowsでPHP/Apache環境構築(ダウンロード~画面を起動するまで)
なぜか自分のパソコンにxamppがダウンロードできなかったので、この記事を参考にApacheサーバーを入れました。

CSS編
サルワカ ChromeでCSSが反映されない?キャッシュ消去で対処
CSSの変更がブラウザになかなか反映されないという問題がこれで解決しました。

JavaScript編
JavaScriptに"Maximum call stack …"で怒られた1例と解決までにやったこと
Google ChromeのデベロッパーツールのPerformanceを使ったエラーの検出方法、Maximum call stack というエラー文の意味について知ることができました。

Samurai Blog【JavaScript入門】誰でも分かるPromiseの使い方とサンプル例まとめ!
実際のWebサイトには実装しませんでしたが、JavaScriptの関数を同期的に使う方法について学べました。

PHP編
【PHP】HTMLSPECIALCHARS関数でエスケープ処理をしてください【XSSの防止】
利用者の入力情報のエスケープの方法について学ぶことができました。

Qiita PHPオブジェクト指向入門(前半)
本だけでは理解しきれなかったPHPの基本について知ることができました。

終わりに

Webサイトを始めて作成した際にブックマークをつけた記事はもう少し多かったのですが、いくつか消してしまったので7割程度しかあげられませんでした。
Webサイトを作成して思ったことは、自分が悩んでいる問題の解決策を無料で教えてくれる現代のネット環境は素晴らしいな、ということでした。
これからも楽しみながらプログラミングに取り組んでいきたいです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Windows10にPHPをインストールする方法

  • 環境
    • Windows10 Pro 64bit

ダウンロードする

PHP本体

  1. PHP For Windows: Binaries and sources ReleasesからPHP7.3「VC15 x86 Thread Safe」のzipファイルをダウンロードする
    • 今回ダウンロードしたのは、php-7.3.14-Win32-VC15-x86.zip
  2. zipファイルを解凍して任意のフォルダに配置する
    • 今回は、C:\apps配下

XDebug

デバックするのでこちらもダウンロードする

  1. Xdebug: Downloadsから「PHP 7.3 VC15 TS (32 bit)」のdllをダウンロードする
    • 今回ダウンロードしたのは、php_xdebug-2.9.1-7.3-vc15.dll
  2. ダウンロードしたdllを C:\apps\php-7.3.14-Win32-VC15-x86\ext 配下に配置する

APCU

使わない場合はとばす

  1. PECL :: Package :: APCuから「Version 5.1.17のDLL」を選択する
    • image.png
  2. PHP7.3の「7.3 Thread Safe (TS) x86」リンクでzipファイルをダウンロードする
    • 今回ダウンロードしたのは、php_apcu-5.1.17-7.3-ts-vc15-x86.zip
  3. zipファイルを解凍して格納されているdllを C:\apps\php-7.3.14-Win32-VC15-x86\ext 配下に配置する

php.iniを作成する

  1. C:\apps\php-7.3.14-Win32-VC15-x86 配下にある php.ini-production または php.ini-development をコピーして php.ini を作成する
  2. 以下部分を環境に合わせて記載する
...省略...
; Directory in which the loadable extensions (modules) reside.
; http://php.net/extension-dir
; extension_dir = "./"
; On windows:
extension_dir="C:\apps\php-7.3.14-Win32-VC15-x86\ext"
...省略...
; Temporary directory for HTTP uploaded files (will use system default if not
; specified).
; http://php.net/upload-tmp-dir
upload_tmp_dir="C:\apps\php-7.3.14-Win32-VC15-x86\tmp"
...省略...
; http://php.net/session.save-path
session.save_path="C:\apps\php-7.3.14-Win32-VC15-x86\tmp"
...省略...↓ここからは追記↓...
[XDebug]
zend_extension = "C:\apps\php-7.3.14-Win32-VC15-x86\ext\php_xdebug-2.9.1-7.3-vc15.dll"
xdebug.profiler_output_dir = "C:\apps\php-7.3.14-Win32-VC15-x86\tmp"
xdebug.remote_log="C:\apps\php-7.3.14-Win32-VC15-x86\tmp\xdebug.txt"
xdebug.trace_output_dir = "C:\apps\php-7.3.14-Win32-VC15-x86\tmp"

PATHを通す

  1. Windows環境変数(PATH)にC:\apps\php-7.3.14-Win32-VC15-x86を設定する
  2. 確認としてPHPのバージョンを確認してみる
$ php -v
PHP 7.3.14 (cli) (built: Jan 21 2020 13:17:19) ( ZTS MSVC15 (Visual C++ 2017) x86 )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.14, Copyright (c) 1998-2018 Zend Technologies
    with Xdebug v2.9.1, Copyright (c) 2002-2020, by Derick Rethans

Apacheに設定する

  1. Apacheをインストールする

httpd.confにPHPを設定する

  1. confフォルダ配下のhttpd.confを開く
  2. 下のほうに以下を追記する
# PHP
LoadModule php7_module "C:/apps/php-7.3.14-Win32-VC15-x86/php7apache2_4.dll"
AddHandler application/x-httpd-php .php
PHPIniDir "C:/apps/php-7.3.14-Win32-VC15-x86"
<IfModule dir_module>
DirectoryIndex index.html index.php
</IfModule>

確認してみる

テスト用ファイルを作成する

  1. DocumentRootに以下の内容でphpinfo.php(テスト用ファイル)を作成する
    • DocumentRootはhttpd.confに設定されており、DocumentRoot "${SRVROOT}/htdocs"(初期値)となっている場合はC:\apps\httpd-2.4.41-o111c-x86-vc15-r2\Apache24\htdocsとなる
phpinfo.php
<?php phpinfo(); ?>

Apacheを起動する

$ sc start Apache2.4

SERVICE_NAME: Apache2.4
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 2  START_PENDING
                                (NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x7d0
        PID                : 10060
        FLAGS              :

確認してみる

http://localhost/phpinfo.php を表示してみる
image.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravelで非同期チャットアプリを作ろう(2)

はじめに

この記事では、片方がコメントを送信したら、もう片方の人はリロードしなくても、コメントが表示されるチャットアプリを作っていきたいと思います。

前回:Laravelで非同期チャットアプリを作ろう(1)

完成物

chat2.gif

ソースコード:https://github.com/Alesion30/ChatApp

非同期通信とは

非同期通信とは、ネットワークなどでつながれているコンピュータ間で、送信者のデータ送信タイミングと受信者のデータ受信タイミングを合わせずに通信を行う通信方式のこと。

参照: 非同期通信 - @IT リッチクライアント用語事典

日常生活の例でいうとこんな感じ。

同期通信

スクリーンショット 2020-01-22 17.47.07.png

非同期通信

スクリーンショット 2020-01-22 17.47.26.png

同期通信の場合は、リクエストを送信したらリロードが入り、他の処理を受け付けなくなるが、非同期通信の場合は、リクエストを送信しても、リロードが入らず別の処理を送信することもできる。

方針

  • APIを作る。(URLにアクセスしたら、jsonデータを返すやつ)
  • JavaScriptで、APIを叩きjsonデータを取得する。
  • ループ処理を用いてjsonデータを、bladeファイルに埋め込む。

APIを作る

HomeController.phpにjsonを返すgetData()という関数を定義する。

app/Http/Controllers/HomeController.php
public function getData()
{
    $comments = Comment::orderBy('created_at', 'desc')->get();
    $json = ["comments" => $comments];
    return response()->json($json);
}

web.phpに、getData()を登録する。

routes/web.php
Route::get('/result/ajax', 'HomeController@getData');

http://localhost/ChatApp/public/result/ajax にアクセスすると、jsonデータが返ってくる。

スクリーンショット 2020-01-22 18.03.40.png

ajaxを使って、jsonを取得する

ajaxを使えるようにするために、app.blade.phpのheadの部分でスクリプトを読み込む。

resources/views/layouts/app.blade.php
<!-- Scripts -->
<script src="{{ asset('js/app.js') }}" defer></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

これはajaxの基本形である。dataTypeには、jsonだけでなく、csvやhtmlも指定できる。

$.ajax({
    url: "result/ajax/",
    dataType: "json",
    success: data => {
      // 成功時の処理
    },
    error: () => {
      // エラー時の処理
    }
})

public/jsフォルダにcomment.jsを新規作成する。5秒ごとに、jsonデータを取得している。

public/js/comment.js
$(function() {
    get_data();
});

function get_data() {
    $.ajax({
        url: "result/ajax/",
        dataType: "json",
        success: data => {
            console.log(data);
        },
        error: () => {
            alert("ajax Error");
        }
    });

    setTimeout("get_data()", 5000);
}

app.blade.phpのbodyタグの一番下に、@yield('js')を入れる。

resources/views/layouts/app.blade.php
        <main class="py-4">
            @yield('content')
        </main>
    </div>

    @yield('js')
</body>

home.blade.phpの一番下で、comment.jsを読み込む。

resources/views/home.blade.php
@section('js')
<script src="{{ asset('js/comment.js') }}"></script>
@endsection

http://localhost/ChatApp/public/home にアクセスして、検証ツールを使うと、5秒ごとにjsonデータが送られてきていることがわかる。

スクリーンショット 2020-01-22 18.16.23.png

comment.jsのsuccessの処理を以下のように書き換えてみる。

public/js/comment.js
success: data => {
    console.log(data.comments);
    for (var i = 0; i < data.comments.length; i++) {
        console.log(data.comments[i].name);
        console.log(data.comments[i].comment);
    }
},

スクリーンショット 2020-01-22 18.29.17.png

ループ処理を用いてjsonデータを、bladeファイルに埋め込む。

home.blade.phpでコメントを表示している部分を書き換える。

resources/views/home.blade.php
<div class="chat-container row justify-content-center">
    <div class="chat-area">
        <div class="card">
            <div class="card-header">Comment</div>
            <div class="card-body chat-card">
                <div id="comment-data"></div>
            </div>
        </div>
    </div>
</div>

JavaScriptで、<div id="comment-data"></div>の中にコメントを埋め込んでいく形になる。

comment.jsのsuccessの処理を以下のように書き換える。

public/js/comment.js
success: data => {
    $("#comment-data")
        .find(".comment-visible")
        .remove();

    for (var i = 0; i < data.comments.length; i++) {
        var html = `
                    <div class="media comment-visible">
                        <div class="media-body comment-body">
                            <div class="row">
                                <span class="comment-body-user" id="name">${data.comments[i].name}</span>
                                <span class="comment-body-time" id="created_at">${data.comments[i].created_at}</span>
                            </div>
                            <span class="comment-body-content" id="comment">${data.comments[i].comment}</span>
                        </div>
                    </div>
                `;

        $("#comment-data").append(html);
    }
},

http://localhost/ChatApp/public/home にアクセスして、コメントを追加するとうまく反映している。

スクリーンショット 2020-01-22 18.32.38.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PHP + mysql を久しぶりにやる前に見ておく

個人的メモ

ダメぜったい

  • xxx.php ファイルの末尾の ?> の後に空行や空白を不用意に入れない。
  • mysql のパスワード書いたファイルを git add しない。

他言語との違いなど

  • 文末にセミコロンが必要
  • 変数名の冒頭に $ が必要
  • 明示的な型変換を必要としない。
    • 強制的に型を決めたいときは $x = (int)$a など。
  • 文字列のクオートは '' または ""。
    • 文字列の連結は .; たとえば $a .= 'hoge' . 'huga';
  • 配列はすべて連想配列扱い。
    • $a[1]$a["1"] と同じ。
  • コメントアウトは //
  • グローバル変数はローカルスコープ内では無効
    • スコープ内で参照するには global $val; が必要
  • 外部ファイルの読み込みは require('filename.php');
    • include は読み込めない場合でもエラーにならない
  • else if, elseif 両方あり。
  • 標準出力への出力は echo:例えば echo $a, $b, $c, "\n";
    • print は引数が一つ。. で連結すれば同じような結果になるが同じではない。
  • nullnil ではなく大文字で NULL
  • next ではなく continue
  • switch 文は基本は C と同じ (case 必要、default あり)。
    • switch 文内の continuebreak 相当
  • for は C と同じ: for ( $i = 0; $i < 100; $i++ ){}
  • foreach もあり
    • foreach ( $array as $val ){}
    • foreach ( $array as $key => $val ){} で key も取り出せる
  • #define の代わりは declare: declare(MAX_NUM=1);
  • クラスのメンバの参照は -> (. は使わない)
  • ヒアドキュメントは <<<END など

コマンドラインで動作確認

$ php -v

httpd サーバで php が動くか確認。

index.php
<?php phpinfo(); ?>

ブラウザで開いたときに、php の情報がずらずらと出たら成功。

基本のコード

pw.php
<?php
    $pw = 'password';
    $user = 'user';
?>
base.php
<?php
    $buf = "";
    $database = "mydb";
    $host = "localhost";
    require("pw.php");

    try {
        $pdo = new PDO('mysql:host=localhost;mydb=iot;charset=utf8',$user,$pw,array(PDO::ATTR_EMULATE_PREPARES => false));
        $query = "select * from mytable;";
        $res = $pdo->query( $query );

    } catch (PDOException $e) {
        exit('DB connection refused.'.$e->getMessage());
    }

    $buf = "";
    foreach( $res as $name ){
        $buf .= $name[1] . "," . $name[2] . "," . $name[3] . "," . $name[4] . "\n";
    }
    echo $buf;
?>

ソースその2

GET や POST の識別、ヘッダの取得など。雰囲気のみなので雑い。

hoge.php
$content_type = explode(';', trim(strtolower($_SERVER['CONTENT_TYPE'])));
$media_type = $content_type[0];

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
  $content = file_get_contents('php://input');
} else if(isset($_GET['name'])) {
    $name = urldecode($_GET['name']);
    error_log( "table:" . $name. "\n", 3, "./error.log");
}else{
    error_log( "GET: no name\n", 3, "./error.log");
    exit(-1);
}

上のコードの error.log は .php ファイルのあるディレクトリを指す。パーミションがなければ書きこめない。

他の言語にあんまりない構文や規則

制御構文をタグの間をまたがって使える

hoge.html
<?php if ($x == 5): ?>
xは5です。
<?php eles ?>
xは5ではありません。
<?php endif; ?>

これは下記とほぼ等価。

hoge.php
<?php 
    if ($x == 5){
        echo "xは5です。";
    }eles{
        echo "xは5ではありません。";
    }
?>

for, while, switch なども同じようなことはできる。

可変変数

$ を重ねて付けて、変数の値そのものを変数名として使える。

hoge.php
<?php
$a = 'test';
$$a = 'hoge';
echo $a;       // test
echo $test;    // hoge
echo ${$a};    // hoge
$test = 'huga';
echo $$a;      // huga
$h = 'bar';
echo ${$a}[0]; // h
echo ${$a[0]}; // bar
?>

配列の添字

配列はすべて順序付きの連想配列として扱われる。添字を数字にすると、小数でも整数と見なされる。true は 1 扱い。false は 0 扱い。(javascriptぽい)

hoge.php
<?php
$array = array(
    1    => "a",
    "1"  => "b",
    1.5  => "c",
    true => "d",
);
var_dump($array);
// array(1) {
//  [1]=>
//  string(1) "d"
//}
?>

echo の短縮

変数の前の等号は echo を意味する。

echo.php
<?php =$val; ?>

これは

echo.php
<?php echo $val; ?>

これと等価。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む