20210110のPHPに関する記事は23件です。

PHP基礎 -繰り返し処理をマスターする-

頻出の構文

繰り返し処理をする上では上の3つの構文を使うことがほとんどです。

while

カッコ内の条件がtrueである限り処理を繰り返します。

何らかの条件でループを脱出する用途に使います。

$i = 1; #初期値の定義

while($i <= 10) { #$iが10以下ならtrue
  echo $i; 
  $i++ #$iの再代入
}

カッコ内では繰り返しの条件のみを設定して、初期値の設定と再代入は外で行います。

再代入を忘れると処理がエンドレスでループされてしまうので注意が必要です。

for

whileと同じく、カッコ内の条件がtrueである限り処理を繰り返しますが、カッコ内で初期値の設定と再代入をまとめて記述します。

for($i = 1; $i <= 10; i++) {
  echo $i;
}

foreach

foreachは配列に対して使う繰り返し文で、配列の中身を順に取り出して処理することができます。

$array = [1, 2, 3];

foreach($arrray as $val){
  echo $val;
}

以下のように記述することで連想配列のキーと値を両方取得することができます

```php
$user = ['name' => 'zeisho', 'password' => 'foobar'];

foreach($user as $key =>$val){
  echo $key, $val;
}

その他の構文

do - while

条件のチェックが最後に実行されること以外はwhile文と同じです。

$i = 1;

do {
  echo $i;
  $i++;
}while(i < 10);
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PHP 入門 忘れそうなものをメモ

改行する方法

echo '<br>';

定数

const ID = 1; 
echo ID; //result:1 

ポイント

const 定数名(全て大文字)で表す
・変数とは反対に、値を上書きできないようにしたいときにconstを使用する

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

PHP命名規則

はじめに

昨日は環境設定を行ったので今日はPHPの変数命名規則について触れたいと思います
テックキャンプと言う今絶賛(いい意味でも悪い意味でも)人気スクールでrubyを少しかじっていたのそれの比較も込になります
違っていると言う意見がありました容赦無く、

Fool = ちげーよ
puts Fool

と叱責してください()

と言うわけでPHPの変数命名規則

さて、先ほど何気なくrubyで代入してputsで出力しましたが、当然PHPでは違います
違うと言うと語弊がありますね
表記の仕方が違うだけで、変数とか代入とか出力は同じです
違うのは言葉が違います

自分語りで申し訳ないのですが、私が大学時代、教授からプログラミング言語は使う言葉が違うだけで、意味合いは同じ、標準語と関西弁くらいの違いと教わりました。
要は何が言いたいかと言うと文法は同じって事ですね

前置きが長くなりましたが

この”Fool”が変数
”ちげーよ”が文字列になります
で、= で変数に文字列が代入され、putsで画面に出力されるとう仕組みでRubyは動いてます

でもPHPはちょいと違います
違うと言っても文法ではなく(ry

  • 最初は必ず$マークをつける
  • 英単語、英単語+数字、日本語OK
  • $マーク後数字、空白、記号はNG
  • ややこしくなるので極力小文字を使用

となっております
$を付けたりするのはrubyではなかったでよね

つまりさっきのFool〜をPHPで表現すると

$fool = ちげーよ
print($fool)

になるわけですね
ちなみにprintと言うのはrubyで言うputsのようなものです
この様に言葉は違いど文法は同じと言う事が伺えますね

以上です
次回はwhile for foreachについて触れたいと思います

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

EC2でartisanが作動しない時にやること

背景

Mac環境でLaravelプロジェクトをAWSのEC2にデプロイしようとしたところ、php artisan key:generatePHP Fatal errarで返ってきてしまいました。
しかし何日かの奮闘の末、解決することが出来たので、同じ悩みを持つ方の手助けに少しでもなればと思いその解決方法を共有させていただきます。

結論:バージョンとcomposer.json

このエラーは
1. composer.jsonの中身がおかしかったこと
2. ローカルのものとEC2上のものでバージョンが違っていたこと
の2点が原因でした。したがってまずcomposer.jsonの中身を書き換えるところから説明していきます。

composer.jsonの中身を書き換える

重要なcomposerのファイルは2種類あります。ここまで来た方なら2つとも既に存在しているファイルです。
composer.json
- composer installを実行する際にはこのjsonファイルの定義を元にパッケージのダウンロードを行う
- composer updateでjsonの定義を元に各バージョンのライブラリををアップデートする。
composer.lock
- composer installでlockに書き出されて各バージョンのライブラリをダウンロードする。

引用 https://qiita.com/a-nishimura/items/8c71085183e0b8a53f6a

したがってcomposer installにおいて、composer.jsonの定義がとても重要になります。しかし私の場合、このjsonファイルが2行しか書かれていませんでした。
確認及び書き換えはvim compose.jsonで行うことが出来ます。内容を確認した後、jsonファイルを以下の内容に書き換えましょう。

{
  "name": "laravel/laravel",
"type": "project",
"description": "The Laravel Framework.",
"keywords": [
    "framework",
    "laravel"
],
"license": "MIT",
"require": {
    "php": "^7.2.5|^8.0",
    "fideloper/proxy": "^4.4",
    "laravel/framework": "^6.20",
    "laravel/tinker": "^2.5"
},
"require-dev": {
    "barryvdh/laravel-debugbar": "^3.3",
    "facade/ignition": "^1.16.4",
    "fakerphp/faker": "^1.9.1",
    "laravel/ui": "^1.2",
    "mockery/mockery": "^1.0",
    "nunomaduro/collision": "^3.0",
    "phpunit/phpunit": "^8.5.8|^9.3.3"
},
"config": {
    "optimize-autoloader": true,
    "preferred-install": "dist",
    "sort-packages": true
},
"extra": {
    "laravel": {
        "dont-discover": []
    }
},
"autoload": {
    "psr-4": {
        "App\\": "app/"
    },
    "classmap": [
        "database/seeds",
        "database/factories"
    ]
},
"autoload-dev": {
    "psr-4": {
        "Tests\\": "tests/"
    }
},
"minimum-stability": "dev",
"prefer-stable": true,
"scripts": {
    "post-autoload-dump": [
        "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
        "@php artisan package:discover --ansi"
    ],
    "post-root-package-install": [
        "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
    ],
    "post-create-project-cmd": [
        "@php artisan key:generate --ansi"
    ]
}

この段階ではまだcomposerのインストールは行いません。
次にバージョン合わせです。

バージョンを合わせる

私の場合、ローカルがPHP7.3、EC2がPHP7.2でした。ということはEC2上でPHPのバージョンを7.2から7.3へと上げなければなりません。以下にそのやり方を記述していきます。
まずPHPのバージョンを確認していきましょう。
php -v
次にバージョンを7.2から7.3へ上げていきます。

sudo amazon-linux-extras disable php7.2
sudo amazon-linux-extras disable lamp-mariadb10.2-php7.2
sudo amazon-linux-extras enable php7.3
sudo yum install php-cli php-pdo php-fpm php-json php-mysqlnd
sudo yum install php-mbstring
sudo yum install php-dom

参考:https://forums.aws.amazon.com/thread.jspa?messageID=908568

composerをインストールする

これで最後です。
composer install

最後に

ここまでお疲れ様でした。最後に、私がこの方法に行き着くまでに試したコマンドを以下に載せようと思います。あとdisableにしているlamp-maraiadb10.2のことを忘れないでくださいね。
composer update
composer update —no-scripts
composer dump-autoload

これらが上手くいかなかったのは、前述の通り大元のcomposer.jsonを書き替えてなかったからだと思います。

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

EC2にLaravelプロジェクトをデプロイする際、artisanが実行できない時にやること

背景

Mac環境でLaravelプロジェクトをAWSのEC2にデプロイしようとしたところ、php artisan key:generatePHP Fatal errarで返ってきてしまいました。
しかし何日かの奮闘の末、解決することが出来たので、同じ悩みを持つ方の手助けに少しでもなればと思いその解決方法を共有させていただきます。

結論:バージョンとcomposer.json

このエラーは
1. composer.jsonの中身がおかしかったこと
2. ローカルのものとEC2上のものでバージョンが違っていたこと
の2点が原因でした。したがってまずcomposer.jsonの中身を書き換えるところから説明していきます。

composer.jsonの中身を書き換える

重要なcomposerのファイルは2種類あります。ここまで来た方なら2つとも既に存在しているファイルです。
composer.json
- composer installを実行する際にはこのjsonファイルの定義を元にパッケージのダウンロードを行う
- composer updateでjsonの定義を元に各バージョンのライブラリををアップデートする。
composer.lock
- composer installでlockに書き出されて各バージョンのライブラリをダウンロードする。

引用 https://qiita.com/a-nishimura/items/8c71085183e0b8a53f6a

したがってcomposer installにおいて、composer.jsonの定義がとても重要になります。しかし私の場合、このjsonファイルが2行しか書かれていませんでした。
確認及び書き換えはvim compose.jsonで行うことが出来ます。内容を確認した後、jsonファイルを以下の内容に書き換えましょう。

{
  "name": "laravel/laravel",
"type": "project",
"description": "The Laravel Framework.",
"keywords": [
    "framework",
    "laravel"
],
"license": "MIT",
"require": {
    "php": "^7.2.5|^8.0",
    "fideloper/proxy": "^4.4",
    "laravel/framework": "^6.20",
    "laravel/tinker": "^2.5"
},
"require-dev": {
    "barryvdh/laravel-debugbar": "^3.3",
    "facade/ignition": "^1.16.4",
    "fakerphp/faker": "^1.9.1",
    "laravel/ui": "^1.2",
    "mockery/mockery": "^1.0",
    "nunomaduro/collision": "^3.0",
    "phpunit/phpunit": "^8.5.8|^9.3.3"
},
"config": {
    "optimize-autoloader": true,
    "preferred-install": "dist",
    "sort-packages": true
},
"extra": {
    "laravel": {
        "dont-discover": []
    }
},
"autoload": {
    "psr-4": {
        "App\\": "app/"
    },
    "classmap": [
        "database/seeds",
        "database/factories"
    ]
},
"autoload-dev": {
    "psr-4": {
        "Tests\\": "tests/"
    }
},
"minimum-stability": "dev",
"prefer-stable": true,
"scripts": {
    "post-autoload-dump": [
        "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
        "@php artisan package:discover --ansi"
    ],
    "post-root-package-install": [
        "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
    ],
    "post-create-project-cmd": [
        "@php artisan key:generate --ansi"
    ]
}

この段階ではまだcomposerのインストールは行いません。
次にバージョン合わせです。

バージョンを合わせる

私の場合、ローカルがPHP7.3、EC2がPHP7.2でした。ということはEC2上でPHPのバージョンを7.2から7.3へと上げなければなりません。以下にそのやり方を記述していきます。
まずPHPのバージョンを確認していきましょう。
php -v
次にバージョンを7.2から7.3へ上げていきます。

sudo amazon-linux-extras disable php7.2
sudo amazon-linux-extras disable lamp-mariadb10.2-php7.2
sudo amazon-linux-extras enable php7.3
sudo yum install php-cli php-pdo php-fpm php-json php-mysqlnd
sudo yum install php-mbstring
sudo yum install php-dom

参考:https://forums.aws.amazon.com/thread.jspa?messageID=908568

composerをインストールする

これで最後です。
composer install

最後に

ここまでお疲れ様でした。最後に、私がこの方法に行き着くまでに試したコマンドを以下に載せようと思います。あとdisableにしているlamp-maraiadb10.2のことを忘れないでくださいね。
composer update
composer update —no-scripts
composer dump-autoload

これらが上手くいかなかったのは、前述の通り大元のcomposer.jsonを書き替えてなかったからだと思います。

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

EC2にLaravelプロジェクトをデプロイしていく中で、artisanが実行できなくなった時にやること

背景

Mac環境でLaravelプロジェクトをAWSのEC2にデプロイしようとしたところ、php artisan key:generatePHP Fatal errarで返ってきてしまいました。
しかし何日かの奮闘の末、解決することが出来たので、同じ悩みを持つ方の手助けに少しでもなればと思いその解決方法を共有させていただきます。

結論:バージョンとcomposer.json

このエラーは
1. composer.jsonの中身がおかしかったこと
2. ローカルのものとEC2上のものでバージョンが違っていたこと
の2点が原因でした。したがってまずcomposer.jsonの中身を書き換えるところから説明していきます。

composer.jsonの中身を書き換える

重要なcomposerのファイルは2種類あります。ここまで来た方なら2つとも既に存在しているファイルです。
composer.json
- composer installを実行する際にはこのjsonファイルの定義を元にパッケージのダウンロードを行う
- composer updateでjsonの定義を元に各バージョンのライブラリををアップデートする。
composer.lock
- composer installでlockに書き出されて各バージョンのライブラリをダウンロードする。

引用 https://qiita.com/a-nishimura/items/8c71085183e0b8a53f6a

したがってcomposer installにおいて、composer.jsonの定義がとても重要になります。しかし私の場合、このjsonファイルが2行しか書かれていませんでした。
確認及び書き換えはvim compose.jsonで行うことが出来ます。内容を確認した後、jsonファイルを以下の内容に書き換えましょう。

{
  "name": "laravel/laravel",
"type": "project",
"description": "The Laravel Framework.",
"keywords": [
    "framework",
    "laravel"
],
"license": "MIT",
"require": {
    "php": "^7.2.5|^8.0",
    "fideloper/proxy": "^4.4",
    "laravel/framework": "^6.20",
    "laravel/tinker": "^2.5"
},
"require-dev": {
    "barryvdh/laravel-debugbar": "^3.3",
    "facade/ignition": "^1.16.4",
    "fakerphp/faker": "^1.9.1",
    "laravel/ui": "^1.2",
    "mockery/mockery": "^1.0",
    "nunomaduro/collision": "^3.0",
    "phpunit/phpunit": "^8.5.8|^9.3.3"
},
"config": {
    "optimize-autoloader": true,
    "preferred-install": "dist",
    "sort-packages": true
},
"extra": {
    "laravel": {
        "dont-discover": []
    }
},
"autoload": {
    "psr-4": {
        "App\\": "app/"
    },
    "classmap": [
        "database/seeds",
        "database/factories"
    ]
},
"autoload-dev": {
    "psr-4": {
        "Tests\\": "tests/"
    }
},
"minimum-stability": "dev",
"prefer-stable": true,
"scripts": {
    "post-autoload-dump": [
        "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
        "@php artisan package:discover --ansi"
    ],
    "post-root-package-install": [
        "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
    ],
    "post-create-project-cmd": [
        "@php artisan key:generate --ansi"
    ]
}

この段階ではまだcomposerのインストールは行いません。
次にバージョン合わせです。

バージョンを合わせる

私の場合、ローカルがPHP7.3、EC2がPHP7.2でした。ということはEC2上でPHPのバージョンを7.2から7.3へと上げなければなりません。以下にそのやり方を記述していきます。
まずPHPのバージョンを確認していきましょう。
php -v
次にバージョンを7.2から7.3へ上げていきます。

sudo amazon-linux-extras disable php7.2
sudo amazon-linux-extras disable lamp-mariadb10.2-php7.2
sudo amazon-linux-extras enable php7.3
sudo yum install php-cli php-pdo php-fpm php-json php-mysqlnd
sudo yum install php-mbstring
sudo yum install php-dom

参考:https://forums.aws.amazon.com/thread.jspa?messageID=908568

composerをインストールする

これで最後です。
composer install

最後に

ここまでお疲れ様でした。最後に、私がこの方法に行き着くまでに試したコマンドを以下に載せようと思います。あとdisableにしているlamp-maraiadb10.2のことを忘れないでくださいね。
composer update
composer update —no-scripts
composer dump-autoload

これらが上手くいかなかったのは、前述の通り大元のcomposer.jsonを書き替えてなかったからだと思います。

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

ORDER BY句はプリペアドステートメントを使えない。解決策。

背景

ポートフォリオで話のアイディアをメモするアプリを作成している。

そのアイディア一覧を表示する画面のお話です。

  • 新着順(デフォルト)
  • 評価順
  • 更新順

この3つのどれかを選択してソートする機能を作りたかった。

自分の情弱な頭で考えたところ、これで普通に解決するはずだった。

//POSTで受け取ったソート変数をプリペアドステートメントに入れる
$category_contents=$db->prepare("SELECT * FROM ideas WHERE category_id=? AND member_id=? ORDER BY ? DESC LIMIT $startdisp , 5");

$category_contents->execute(array($category_id,$member_id,$sort));
$ideas=$category_contents->fetchAll();

だが、、、
エラーが出る。。。

解決策

調べてみたところORDER BY句はプリペアドメソッドを使えないというではないか。。。

解決策として、POSTで受け取った$sortの値を見てswitch文で条件分岐させることにした。

//POST送信されてきたsortの値を取得
if(!empty($_POST["sort"])){
    h($sort=$_POST["sort"]);
}

if($sort){
    //ORDER BY句はプリペアドステートメントを使えないので、switch文で条件分岐
    switch($sort){
        case 'self_evaluate':
          $category_contents=$db->prepare("SELECT * FROM ideas WHERE category_id=? AND member_id=? ORDER BY self_evaluate DESC LIMIT $startdisp , 5");
          $category_contents->execute(array($category_id,$member_id));
        break;

        case 'modified':
            $category_contents=$db->prepare("SELECT * FROM ideas WHERE category_id=? AND member_id=? ORDER BY modified DESC LIMIT $startdisp , 5");
            $category_contents->execute(array($category_id,$member_id));
        break;

        default:
            $category_contents=$db->prepare("SELECT * FROM ideas WHERE category_id=? AND member_id=? ORDER BY created DESC LIMIT $startdisp , 5");
            $category_contents->execute(array($category_id,$member_id));
    }
}else{
    $category_contents=$db->prepare("SELECT * FROM ideas WHERE category_id=? AND member_id=? ORDER BY created DESC LIMIT $startdisp , 5");
    $category_contents->execute(array($category_id,$member_id));
}

$ideas=$category_contents->fetchAll();

これでうまく動作した。
以上。

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

aタグでPOST送信したい

背景

次のページにページングした際に、
ソートで並び替えたコンテンツがデフォルトのソート設定に戻ってしまう現象を解決したかった。
(例:1ページ目では更新順に並び替えたが、2ページ目ではデフォルトの新着順に並び変わっている)

解決方

javascriptを用いて$sortの値をPOST送信した。

  <form method="post" name="form2" action="./list.php?category=<?=$category_id?>&page=<?=$page+1?>">
    <input type="hidden" name="sort" value=<?=$sort?>>
    <a href="javascript:form2.submit()">次へ</a>
  </form>

以上。

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

PHPでセキュリティを意識しまくって自動ログイン処理を作ってみた

背景

ポートフォリオの自動ログイン処理の部分です。

フレームワークを触ったことがないので、
純粋なphpだけでセキュリティの部分を意識しながら作ってみました。

データベースやクッキー、セッションを総動員して自動ログイン処理を実現しています。
初心者なので間違いなどあれば教えていただけるとありがたいです。

初回のログイン処理。

①※オートログインにチェック有の時のみ

ランダムトークンを生成

bin2hex(random_bytes(32));

②※オートログインにチェック有の時のみ

生成したトークンを、データベースとクッキーに保存する。
これによりクッキーが消去されるまで自動ログインが有効になる。
ここで1人のユーザが、データベースに複数のトークンを保持しないように以下の処理をおこなう。

//自動ログインにチェックが入っているとき
  if($_POST["auto_login"]==="on"){
      $auto_login_token=bin2hex(random_bytes(32));
      //自動ログイントークンをクッキーに保存
      setcookie("auto_login",$auto_login_token,time()+60*60*24*7);

      //ログインしたユーザの自動ログイントークンが既にdbにないか確認
      $exist=$db->prepare("SELECT * FROM auto_login WHERE user_id=?");
      $exist->execute(array($user["id"]));

      //既に自動ログイントークンが存在する場合は、データベースのトークンを更新
      if($exist->fetch()){
        $update_key=$db->prepare("UPDATE auto_login SET auto_login_key=? WHERE user_id=?");
        $update_key->execute(array(
          $auto_login_token,
          $user["id"]
        ));
      }
      //自動ログイントークンがない場合は新規でレコードを追加
      else{
        $state=$db->prepare("INSERT INTO auto_login VALUES(?,?)");
        $state->execute(array(
        $user["id"],
        $auto_login_token
        ));
    }
  }

セッションハイジャックを防ぐためにセッションidを更新。

session_regenerate_id(true);

セッションにユーザーidを保存する

$_SESSION["user_id"]=$user["id"];

この情報がない状態でログイン先の各ページにリンクしようとすると、ログイン画面に戻される。

//ログインチェックを、ログイン後の全てのページで行う
function login_check(){
    session_start();
    if(!isset($_SESSION["user_id"])){
      header("Location:http://localhost:8888/Portfolio/index.php");
    }
}

ログイン先のページへ移動する。

header("Location:./talkcontents/index.php");
exit();

自動ログイン情報が保存されていた時のログイン処理

クッキーとデータベースのトークンを比較する。

//オートログイン情報がクッキーに保存されている時データベースと比較
if(isset($_COOKIE["auto_login"])){
  $auto_login=$db->prepare("SELECT * FROM auto_login WHERE auto_login_key=?");
  $auto_login->execute(array(h($_COOKIE["auto_login"])));
  $auto_login_info=$auto_login->fetch();

一致したときは、セッションidを更新後、ユーザidをセッションに保存。

//自動ログイントークンが一致したとき
if($auto_login_info){
  session_regenerate_id(true);
  $_SESSION["user_id"]=$auto_login_info["user_id"];
  header("Location:./talkcontents/index.php");
  exit();

クッキーのトークンが一致しなかったときはクッキーのトークンを消去する。

else{
  //クッキーとデータベースで、自動ログイントークンが一致しない場合は、クッキーからトークンを消去
  setcookie("auto_login",$auto_login_token,time()-60*60*24*7);
  header("Location:./index.php");
  exit();
}

コード

//オートログイン情報がクッキーに保存されている時データベースと比較
if(isset($_COOKIE["auto_login"])){
  $auto_login=$db->prepare("SELECT * FROM auto_login WHERE auto_login_key=?");
  $auto_login->execute(array(h($_COOKIE["auto_login"])));
  $auto_login_info=$auto_login->fetch();

  //自動ログイントークンが一致したとき
  if($auto_login_info){
    session_regenerate_id(true);
    $_SESSION["user_id"]=$auto_login_info["user_id"];
    header("Location:./talkcontents/index.php");
    exit();
  }else{
    //クッキーとデータベースで、自動ログイントークンが一致しない場合は、クッキーからトークンを消去
    setcookie("auto_login",$auto_login_token,time()-60*60*24*7);
    header("Location:./index.php");
    exit();
  }
}

//emailとpasswordが入力して送られてきた時
if($_POST){
    //入力されたメールアドレスとパスワードをデータベースと照合
    if(!empty($_POST["email"])&&!empty($_POST["password"])){
        $login=$db->prepare("SELECT * FROM users WHERE email=? AND password=?");
        $login->execute(array(
            h($_POST["email"]),
            h(sha1($_POST["password"]))
        ));
        $user=$login->fetch();

        //一致するデータがあったとき
        if($user){
        //自動ログインにチェックが入っているとき
          if($_POST["auto_login"]==="on"){
              $auto_login_token=bin2hex(random_bytes(32));
              //自動ログイントークンをクッキーに保存
              setcookie("auto_login",$auto_login_token,time()+60*60*24*7);

              //ログインしたユーザの自動ログイントークンが既にdbにないか確認
              $exist=$db->prepare("SELECT * FROM auto_login WHERE user_id=?");
              $exist->execute(array($user["id"]));

              //既に自動ログイントークンが存在する場合は、データベースのトークンを更新
              if($exist->fetch()){
                $update_key=$db->prepare("UPDATE auto_login SET auto_login_key=? WHERE user_id=?");
                $update_key->execute(array(
                  $auto_login_token,
                  $user["id"]
                ));
              }
              //自動ログイントークンがない場合は新規でレコードを追加
              else{
                $state=$db->prepare("INSERT INTO auto_login VALUES(?,?)");
                $state->execute(array(
                $user["id"],
                $auto_login_token
                ));
            }
          }
            //ログインする際にはセッションidを更新する(セッションハイジャック対策)
            session_regenerate_id(true);
            $_SESSION["user_id"]=$user["id"];
            header("Location:./talkcontents/index.php");
            exit();
        }else{
            $error["input"]="nouser";
        }
    }else{
        $error["input"]="blank";
    }
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vessel で Laravel のステップ実行が止まらなくなったら Xdebug のバージョンを確認しよう

概要

Vessel の PHP 環境にインストールされる Xdebug のメジャーバージョンアップによって、リモートでバッグ時のステップ実行が止まらなくなった。
ステップ実行をするためには、Vessel の設定を Xdebug 3 に対応した内容に変更する必要がある。

Vessel とは

Vessel は Docker を使った Laravel のアプリケーション開発環境

Vessel - Docker dev environments for Laravel
https://vessel.shippingdocker.com/

Xdebug とは

PHPのデバッグ用拡張モジュール

Xdebug - Debugger and Profiler Tool for PHP
https://xdebug.org/

ステップ実行が止まらなくなった原因

  • Vessel は環境を作る際に PECL で最新版の Xdebug をインストールしている。
  • 2020年11月25日に Xdebug 3 がリリースされた。
  • Xdebug 3 から php.ini で指定するリモートデバッグの設定が変更されたが、Vessel は Xdebug 2 の設定になっている。
  • Xdebug 3 リリース以降にビルドした Vessel の開発環境は、設定を変更しないと Xdebug でリモートデバッグができなくなった。

Xdebug 3 で何が変わったのか

Upgrading from Xdebug 2 to 3
https://xdebug.org/docs/upgrade_guide

以下、ポイントだけまとめると、

1. ステップ実行を有効にする設定が変わった

Xdebug 2 : xdebug.remote_enable = 1
Xdebug 3 : xdebug.mode=debug

2. Xdebugから接続するアドレスの設定項目が変わった

Xdebug 2 : xdebug.remote_host = ホスト名/IPアドレス
Xdebug 3 : xdebug.client_host = ホスト名/IPアドレス

3. Xdebugから接続するポートの設定項目とポート番号が変わった

Xdebug 2 : xdebug.remote_port = 9000
Xdebug 3 : xdebug.client_port = 9003

Xdebug 3 の設定コンセプト

機能ごとに設定で有効化していた Xdebug 2 に対して、Xdebug 3 では「モード」を指定することで目的の状態に設定するという考え方だそう。このモードを設定するのが xdebug.mode ということ。

あと、remote_* という設定項目が client_* になった。
Xdebug 2 の時は、手元の開発環境は Xdebug から見た「リモート」という意味だったのに対して、
Xdebug 3 は Xdebug が「サーバ」で動作していて開発しているローカル環境が「クライアント」という意味なのだろう。
直感的で分かりやすくなったと思うが、互換性が...

Vessel の設定を Xdebug 3 に対応させる手順

Vessel の開発環境を作成

まずは通常通りの手順で Vessel の開発環境を作成する。

↓公式サイトの手順はこちら

Getting Started
https://vessel.shippingdocker.com/docs/get-started/

開発環境が作成できたらアプケーションが正しく動作することを確認しておく。

Xdebug の設定を変更する

設定を変更するファイル

docker/app/xdebug.ini

% tree
.
├── LICENSE
├── README.md
├── app
├── artisan
├── bootstrap
├── composer.json
├── composer.lock
├── config
├── database
├── docker
│   ├── app
│   │   ├── Dockerfile
│   │   ├── default
│   │   ├── h5bp
│   │   ├── start-container
│   │   ├── supervisord.conf
│   │   ├── vessel.ini
│   │   └── xdebug.ini          ← このファイルを編集する
│   ├── mysql
│   │   ├── conf.d
│   │   └── logs
│   └── node
│       └── Dockerfile
├── docker-compose.yml
├── package.json
├── phpunit.xml
├── public
├── resources
├── routes
├── server.php
├── storage
├── tests
├── vendor
├── vessel
└── webpack.mix.js

Xdebug 3 の設定内容

zend_extension=xdebug.so
xdebug.remote_enable=1
xdebug.remote_handler=dbgp
xdebug.remote_port=9000
xdebug.remote_autostart=1
xdebug.remote_connect_back=0
xdebug.idekey=docker
xdebug.remote_host=192.168.1.2
xdebug.max_nesting_level = 500
; ↑ XDebug 2 の設定

; XDebug 3 の設定 ※ここを追加する
xdebug.mode = debug
xdebug.client_host = host.docker.internal ← コンテナから見たホストのIPアドレス
; xdebug.client_port = 9000 ← XDebug 2 と同じポート 9000 に接続する場合はここで指定

host.docker.internal はコンテナから見たホストのIPアドレスを自動解決する設定
https://docs.docker.jp/docker-for-mac/networking.html

変更した設定を反映する

xdebug.ini の設定を反映させるためにはコンテナをビルドして再起動する。

./vessel stop
./vessel build
./vessel start

IDE で必要な設定を行う

Xdebug 3 が接続してくるポートが 9000 から 9003 に変更になったので、IDE 側で待ち受けるポート番号も 9003 に変えておく。

または、xdebug.ini で Xdebug 3 の接続ポートを 9000 に変えてもよい。

PhpStorp

Configure Xdebug - PhpStorm
https://www.jetbrains.com/help/phpstorm/configuring-xdebug.html

Visual Studio

デバッグ構成ファイルの設定例
https://github.com/aibax/vessel-xdebug3-sample/blob/main/.vscode/launch.json

参考

この件についてサンプルコードを書きました
https://github.com/aibax/vessel-xdebug3-sample

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

WordPress構築作業の備忘録

構築環境

  • Win10-32bit版 Diginnos-StickPC-HDD32GB
  • Apache2.4
  • PHP8
  • MariaDB10.5
  • WordPress5.6

Apache2.4のインストール

公式ページから入手
インストール手順は、こちらのサイトを参考に作業

任意パスに配置

仮にインストールパスを以下に設定
c:/Apache24

httpd.conf の内容を設定

c:/Apache24/conf/httpd.conf

ルートパスを指定

Define SRVROOT "c:/Apache24/"
ServerRoot "${SRVROOT}"

ポート番号を指定

Listen 80

ServerName を指定

ServerName localhost:80

PHP8 のインストール

公式ページから入手
1. Downloads
2. Current Stable PHP 8.0.1 のWindows downloads
3. VS16 x86 Thread Safe の zip をダウンロード ※今回はWin-32bit版を入手

任意のパスに配置

仮にインストールパスを以下に設定
c:/php8

PHP.ini の設定を行う

c:/php8/に存在するphp.ini-developmentをコピーして、php.iniにリネーム

extension_dir を編集する

;extension_dir = "./"
; On windows:
;extension_dir = "ext"
  ↓
extension_dir = "C:/php8/ext"
; On windows:
;extension_dir = "ext"

※2個あるけど、今回は片方だけ設定した、絶対パスと相対パスの指定らしい

他のextension を編集する

;extension=gd
;extension=mbstring
  ↓
extension=gd
extension=mbstring
  • gd ... 画像処理系のなんかを有効
  • mbstring ... マルチバイト文字列のなんかを有効

環境変数の設定でPHP8にパスを通す

  1. WindowsのエクスプローラからPCを右クリック
  2. プロパティ
  3. システムの詳細設定
  4. 環境変数
  5. システム環境変数の Path を編集
  6. c:/php8 のパスをリストに追加する

PHPにパスが通ってるかチェック

  1. Windows のスタートメニュー右のコルタナから、cmd と入力してEnterを押下し、コマンドプロンプトを起動
  2. コマンドプロンプト上で、php -version と入力してパス通過をチェック
  • 失敗時
'php' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。
  • 成功時
PHP 8.0.1 (cli) (built: Jan  5 2021 23:45:55) ( ZTS Visual C++ 2019 x86 )
Copyright (c) The PHP Group
Zend Engine v4.0.1, Copyright (c) Zend Technologies

MariaDB10.5 をインストール

公式ページから入手
1. Download
2. Architecture を32bit用(x86) に変更して msi パッケージでダウンロード
3. DLした msi を実行し、インストールを行う
インストール時の手順はこちらのサイトを参考に作業

MariaDBクライアントを起動

スタートメニューからMariaDBクライアントを起動する
※コマンドプロンプトと同じ黒画面が起動する

WordPress用のデータベースを作成する

  • MariaDBクライアント上でコマンドを実行してデータベースの作成を行う
create database wordpressdb;

とコマンドを実行すると、wordpressdb の名称でデータベースが作成される

使用するDBをwordpressdb に切り替える

use database wordpressdb;

wordpress をインストール

日本語版公式ページから入手
1. トップのwordpressを入手ボタンから入手する

wordpressの構成を任意パスに配置

c:/Apache24/htdocs以下にblogフォルダを作成し、wordpressのファイルを配置
c:/apache24/htdocs/blog/readme.htmlの構成

wordpressのconfigファイルを編集

  1. c:/apache24/htdocs/blog/以下に存在するwp-config-sample.phpをコピーしwp-config.phpにリネームする
  2. 下記項目を設定する
// ** MySQL 設定 - この情報はホスティング先から入手してください。 ** //
/** WordPress のためのデータベース名 */
define( 'DB_NAME', 'database_name_here' );

/** MySQL データベースのユーザー名 */
define( 'DB_USER', 'username_here' );

/** MySQL データベースのパスワード */
define( 'DB_PASSWORD', 'password_here' );

/** MySQL のホスト名 */
define( 'DB_HOST', 'localhost' );

/** データベースのテーブルを作成する際のデータベースの文字セット */
define( 'DB_CHARSET', 'utf8' );

/** データベースの照合順序 (ほとんどの場合変更する必要はありません) */
define( 'DB_COLLATE', '' );
  • DB_NAME -> MariaDB で作成したデータベース名 ※今回は wordpressdb
  • DB_USER -> MariaDB のユーザー名、よくわからなかったので、とりあえず、root を指定
  • DB_PASSWORD -> MariaDB をインストールした際に設定した、パスワードを設定 **********
  • DB_HOST -> MariaDBを置いてるホスト名、localhostで良さげ、外部のDBを使う場合は、URLを指定とかになると思う
  • DB_CHARSET -> MariaDB の設定で使用する文字コードの設定っぽい、よくわからんけど、まぁ良い

認証キーを設定する

phpファイル内に、自動生成のURLが記載されてるので、それを利用して作成したものを、張り付ける

define( 'AUTH_KEY',         'put your unique phrase here' );
define( 'SECURE_AUTH_KEY',  'put your unique phrase here' );
define( 'LOGGED_IN_KEY',    'put your unique phrase here' );
define( 'NONCE_KEY',        'put your unique phrase here' );
define( 'AUTH_SALT',        'put your unique phrase here' );
define( 'SECURE_AUTH_SALT', 'put your unique phrase here' );
define( 'LOGGED_IN_SALT',   'put your unique phrase here' );
define( 'NONCE_SALT',       'put your unique phrase here' );

WordPressの install スクリプトで、DBなど構成要素を作成する

Chrome等のブラウザで、 localhost:80/blog/wp-admin/install.phpにアクセスして、
ワードプレスの作成画面を起動しようと思ったら、以下のエラーが出て悩む

Fatal error: Uncaught Error: Call to undefined function mysql_connect()

php.iniの設定が不足していたので追加する

c:/php8/php.ini

;extension=mysqli
  ↓
extension=mysqli
  • mysqli ... wordpressのDBでMySQL(MariaDB)を使うので有効

Apacheの設定も不足していたので追加する

c:/apache24/conf/httpd.confに設定追加

LoadModule php_module "C:/php8/php8apache2_4.dll"
PHPIniDir "C:/php8"
AddHandler application/x-httpd-php .php

再度アクセスしてみるが症状が変わらない

Fatal error: Uncaught Error: Call to undefined function mysql_connect()
  • php.ini と httpd.conf を更新したのに、apache のサービスを再起動してなかった

  • apache サービスを再起動して、再度アクセスすると無事インストールスクリプトが起動して、インストールが完了

2021/01/11 追記

公開用URLにアクセスしても、ディレクトリ構成がブラウザに表示されてしまうので原因を調査

原因: apache の設定が不足していた

apache の httpd.conf の設定に以下の項目があるので設定が必要

index.htmlの他に、index.php も呼び出せるようにしておく必要があったみたい

#
# DirectoryIndex: sets the file that Apache will serve if a directory
# is requested.
#
<IfModule dir_module>
    DirectoryIndex index.html
</IfModule>
  ↓
<IfModule dir_module>
    DirectoryIndex index.html
    DirectoryIndex index.php
</IfModule>

設定して、apache サービスを再起動して、アクセスすると、トップページが表示された。

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

PHP/Laravel アプリ開発時に知っていると便利かもしれないTips

はじめに

Laravelアプリ開発時に知っていると便利かもしれないTipsをまとめてみます。
初投稿のため不慣れな点が多々あります。ご容赦の程よろしくお願いいたします。
また、PHPは門外漢のため、慣例を無視したものや不自然な記述等あるかもしれません。
その点もご留意ください。

Laravelのバージョンは6.2にて確認を行っています。
バージョンの差異によって動作に差異がある場合があります。

指摘や情報展開等、ご自由にコメントいただけると幸いです。

Laravelのcsrfトークンを用いて多重submitを抑止する

LaravelのsessionオブジェクトはStartSession.phpにて以下の仕様となっている。

  • requestを受け取ったのち、処理の最初の方でsessionストレージから情報を取得し、
    Store.phpインスタンスとして状態を保持する。
  • responseの直前でStore.phpインスタンスの状態をsessionストレージに保存する。

sessionの状態が保存される前に受け取った複数のリクエスト間にて、session情報は最新の状態で同期されない。そのため、submitボタンの連打等によって多重送信を受け取った際、最初のリクエストにてsessionオブジェクトのcsrfトークンの値を変更したとしても、2つ目以降のリクエストが取得したsessionオブジェクトには反映されておらず、そのままの状態では多重送信の抑止が行えない。
csrfトークンを用いて多重サブミットを抑止したい場合、抑止したい処理にて明示的に最新のsession情報を取得し、クライアントのパラメータの値と比較した後、問題がなければ新たなトークンを生成してsessionを保存するといった処理を行う必要がある。

Trait等に以下のような関数を定義する。

Trait.php
private function multiSubmitCheck(Request $request)
{
    // Sessionオブジェクト(Store.php)
    $session = $request->session();
    // Sessionオブジェクトを最新化
    $session->start();
    // csrfトークンと画面パラメータのcsrfトークンの値が異なる場合エラー
    if ($session->token() != $request->input('_token')) {
        return false;
    }
    // csrfトークンの再生成 
    // Store #regenerate によるセッションID再生成でもトークンの再生成が行われる
    $session->regenerateToken();
    // Sessionを保存
    $session->save();

    return true;
}

そして多重サブミットを防ぎたい処理にて上記関数を呼び出し、
戻り値にfalseを返すようであればabortヘルパでエラーを返すなりしてやればよい。

Controller.php
public function update(Request $request)
{
    // 多重サブミットチェック
    if (!this->multiSubmitCheck($request)) abort(409);
    ...
}

加えて、一般的なクライアントサイドにおける多重submit抑止の処理も、不要リクエストの抑制、意図せぬエラー発生の防止等期待できるため、可能な限り行うべきだと思われる。

app.js
const triggers = $('a,button')
$('form').on('submit', function () {
    triggers.css('pointer-events', 'none')
})

デフォルトのペジネーション機能をpostによるsubmitに変更

bladeにてページネーション結果の表示を行う際、各ページのボタンはリンクとして生成され、ページボタンを押下するとgetによる画面遷移が行われる。様々な理由により、検索処理はpostによるリクエストに紐づけて作成しており、ページネーション機能もpostによるsubmitの方が都合がよいといった場面があると思われる。
Eloquent queryのpaginateメソッドは、requestのパラメータ内にpageというキーが含まれてさえいればgetだろうとpostだろうと問題なく動作するようなので、ページネーションボタン押下時の処理にカスタマイズを入れる。

まず、JavaScriptにてページボタン押下時の処理を定義する。

app.js
function pagination(page) {
    const form = $(event.target).closest('form')
    const action = `${form.attr('action')}?page=${page}`
    form.attr('action', action).submit()
}

後はページボタン押下時に上記関数を呼び出すだけ。
公式のドキュメントを参考にページネーションビューを出力し、
bootstrap-4.blade.phpファイルに対して以下のカスタマイズを行う。

bootstrap-4.blade.php
{{-- 11行目を以下に書き換え --}}
<a class="page-link" rel="prev" aria-lavel="@lang('pagination.previous')" onclick="pagination({{ $paginator->currentPage() - 1 }});">&lsaquo;</a>

{{-- 29行目を以下に書き換え --}}
<a class="page-link" onclick="pagination({{ $page }});">{{ $page }}</a>

{{-- 39行目を以下に書き換え --}}
<a class="page-link" rel="next" aria-lavel="@lang('pagination.next')" onclick="pagination({{ $paginator->currentPage() + 1 }});">&rsaquo;</a>

このカスタマイズはページボタンの直近の祖先(親)要素のformに対して、クエリストリングでpageパラメータを付与した後にsubmitしているだけとなる。状況に応じて適宜内容変更することで、様々なケースに対応できると思われる。

404発生時に認証ディレクティブが正常に動作しない問題への対策

404発生時、bladeにて@auth@guestといった認証ディレクティブが、
認証状態にかかわらず@guestの分岐となる場合がある。
レイアウトのbladeにてログイン状態に応じてログイン/ログアウトのボタンの出し分けを行っている場合等、少々不都合があるため対策を講じる必要がある。

内部実装を詳細に追ったわけではないので正確な情報は不明だが、認証ディレクティブを正常に動作させるためには、ルート定義ファイルにリクエストを経由させることが必要なようである。
そのため、未定義ルートでも一度web.phpにて拾ってやり、そのうえで404を返してやることで認証ディレクティブが正常に動作した。

web.php
// リクエストが他ルートに一致しない場合
Route::fallback(function () {
    abort(404);
});

情報求む

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

PHP/Laravelアプリ開発時に知っていると便利かもしれないTips

はじめに

Laravelアプリ開発時に知っていると便利かもしれないTipsをまとめてみます。
初投稿のため不慣れな点が多々あります。ご容赦の程よろしくお願いいたします。
また、PHPは門外漢のため、慣例を無視したものや不自然な記述等あるかもしれません。
その点もご留意ください。

Laravelのバージョンは6.2にて確認を行っています。
バージョンの差異によって動作に差異がある場合があります。

指摘や情報展開等、ご自由にコメントいただけると幸いです。

Laravelのcsrfトークンを用いて多重submitを抑止する

LaravelのsessionオブジェクトはStartSession.phpにて以下の仕様となっている。

  • requestを受け取ったのち、処理の最初の方でsessionストレージから情報を取得し、
    Store.phpインスタンスとして状態を保持する。
  • responseの直前でStore.phpインスタンスの状態をsessionストレージに保存する。

sessionの状態が保存される前に受け取った複数のリクエスト間にて、session情報は最新の状態で同期されない。
そのため、submitボタンの連打等によって多重送信を受け取った際、最初のリクエストにてsessionオブジェクトのcsrfトークンの値を変更したとしても、2つ目以降のリクエストが取得したsessionオブジェクトには反映されておらず、そのままの状態では多重送信の抑止が行えない。
csrfトークンを用いて多重サブミットを抑止したい場合、抑止したい処理にて明示的に最新のsession情報を取得し、クライアントのパラメータの値と比較した後、問題がなければ新たなトークンを生成してsessionを保存するといった処理を行う必要がある。

Trait等に以下のような関数を定義する。

Trait.php
private function multiSubmitCheck(Request $request)
{
    // Sessionオブジェクト(Store.php)
    $session = $request->session();
    // Sessionオブジェクトを最新化
    $session->start();
    // csrfトークンと画面パラメータのcsrfトークンの値が異なる場合エラー
    if ($session->token() != $request->input('_token')) {
        return false;
    }
    // csrfトークンの再生成 
    // Store #regenerate によるセッションID再生成でもトークンの再生成が行われる
    $session->regenerateToken();
    // Sessionを保存
    $session->save();

    return true;
}

そして多重サブミットを防ぎたい処理にて上記関数を呼び出し、
戻り値にfalseを返すようであればabortヘルパでエラーを返すなりしてやればよい。

Controller.php
public function update(Request $request)
{
    // 多重サブミットチェック
    if (!this->multiSubmitCheck($request)) abort(409);
    ...
}

加えて、一般的なクライアントサイドにおける多重submit抑止の処理も、不要リクエストの抑制、意図せぬエラー発生の防止等期待できるため、可能な限り行うべきだと思われる。

app.js
const triggers = $('a,button')
$('form').on('submit', function () {
    triggers.css('pointer-events', 'none')
})

デフォルトのペジネーション機能をpostによるsubmitに変更

bladeにてページネーション結果の表示を行う際、各ページのボタンはリンクとして生成され、ページボタンを押下するとgetによる画面遷移が行われる。様々な理由により、検索処理はpostによるリクエストに紐づけて作成しており、ページネーション機能もpostによるsubmitの方が都合がよいといった場面があると思われる。
Eloquent queryのpaginateメソッドは、requestのパラメータ内にpageというキーが含まれてさえいればgetだろうとpostだろうと問題なく動作するようなので、ページネーションボタン押下時の処理にカスタマイズを入れる。

まず、JavaScriptにてページボタン押下時の処理を定義する。

app.js
function pagination(page) {
    const form = $(event.target).closest('form')
    const action = `${form.attr('action')}?page=${page}`
    form.attr('action', action).submit()
}

後はページボタン押下時に上記関数を呼び出すだけ。
公式のドキュメントを参考にページネーションビューを出力し、
bootstrap-4.blade.phpファイルに対して以下のカスタマイズを行う。

bootstrap-4.blade.php
{{-- 11行目を以下に書き換え --}}
<a class="page-link" rel="prev" aria-lavel="@lang('pagination.previous')" onclick="pagination({{ $paginator->currentPage() - 1 }});">&lsaquo;</a>

{{-- 29行目を以下に書き換え --}}
<a class="page-link" onclick="pagination({{ $page }});">{{ $page }}</a>

{{-- 39行目を以下に書き換え --}}
<a class="page-link" rel="next" aria-lavel="@lang('pagination.next')" onclick="pagination({{ $paginator->currentPage() + 1 }});">&rsaquo;</a>

このカスタマイズはページボタンの直近の祖先(親)要素のformに対して、クエリストリングでpageパラメータを付与した後にsubmitしているだけとなる。状況に応じて適宜内容変更することで、様々なケースに対応できると思われる。

404発生時に認証ディレクティブが正常に動作しない問題への対策

404発生時、bladeにて@auth@guestといった認証ディレクティブが、認証状態にかかわらず@guestの分岐となる場合がある。レイアウトのbladeにてログイン状態に応じてログイン/ログアウトのボタンの出し分けを行っている場合等、少々不都合があるため対策を講じる必要がある。

内部実装を詳細に追ったわけではないので正確な情報は不明だが、認証ディレクティブを正常に動作させるためには、ルート定義ファイルにリクエストを経由させることが必要なようである。
そのため、未定義ルートでも一度web.phpにて拾ってやり、そのうえで404を返してやることで認証ディレクティブが正常に動作した。

web.php
// リクエストが他ルートに一致しない場合
Route::fallback(function () {
    abort(404);
});

情報求む

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

cakephp3のインストール

cakephp3(cakephp3.9)を使用することが増えそうだったので、
忘れないようにインストール方法をまとめることにした

ついでに、cakephp3公式のスタートアップのガイドはこちら
https://book.cakephp.org/3/ja/quickstart.html

今回はvagrantを使用し、php7.1環境にセットアップします
※cakephp3はPHP7.4 (最小は PHP 5.6)の環境が必要です

インストール

インストールはcomposerを使用

curl -s https://getcomposer.org/installer | php
php composer.phar create-project --prefer-dist cakephp/app:^3.8 cms

しかし、エラー、、

Install of cakephp/plugin-installer failed
[RuntimeException]
Could not delete /var/www/html/cakephp3/cms/vendor/cakephp/plugin-installer /tests:

調べてみたら、vagrant特有のエラーみたいです
--no-pluginsを付与すればいいみたいです

php composer.phar create-project --prefer-dist --no-plugins cakephp/app:^3.8 cms

インストールはできたが警告が...

Action required!

The CakePHP plugin installer v1.3+ no longer requires the "post-autoload-dump" hook. Please update your app's composer.json file and remove usage of Cake\Composer\Installer\PluginInstaller::postAutoloadDump

https://tt-computing.com/cake4-remove-post-autoload-dump
こちらのページによるとcomposer.jsonのここの部分削除したら問題ないみたいです、これでバッチリ

"post-autoload-dump":"Cake\\Composer\\Installer\\PluginInstaller::postAutoloadDump"

DBの設定

使用するためのデータベースを作成してください
今回、確認のためだけだったので、スタートアップにあったSQL使いました
https://book.cakephp.org/3/ja/quickstart.html#cms

config/app.php
の以下の部分を正しいものに書き換えます

<?php
return [
    // 上には他の設定があります
    'Datasources' => [
        'default' => [
            'className' => 'Cake\Database\Connection',
            'driver' => 'Cake\Database\Driver\Mysql',
            'persistent' => false,
            'host' => 'localhost',
            'username' => '[MySqlユーザー名]',
            'password' => '[MySqlパスワード]',
            'database' => '[データベース名]',
            'encoding' => 'utf8mb4',
            'timezone' => 'UTC',
            'cacheMetadata' => true,
        ],
    ],
    // 下には他の設定があります
];

ここまでがcakephpの公式にある内容なのですが、、
スクリーンショット 2021-01-04 1.14.26.png

あれ、、データベースでエラー出てますね、、設定は間違いないはずなのになんで、、、?

調べてみると3.9からの機能でapp_local.phpというものがあり、こちらも設定
テスト用に作られたファイルみたいです。
こちらも設定した方が良さそうですね、、、
一旦、試したいだけだったので、本番と同じDB情報を設定します

参考URL
https://coodip.com/articles/3649

スクリーンショット 2021-01-04 1.14.47.png

成功したみたいです。
よかった!
基本的なセットアップはここまでになります^^

bakeコマンド

必要に応じて、モデル、ビュー、コントローラー作る必要があります
bake の後にどれを作る種類を選択し、その後に名前を指定するとcake側で基本に沿ったファイルを作ってくれます。
最初にファイルを作る時、勝手に作ってくれるのでこれは覚えておくと便利!

 php ./bin/cake.php bake model users
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

オブジェクトとは

関連する変数(値)と関数(動作)をまとめて、そのまとまりに名前を付けたものです。これまで、変数と関数は別々に宣言され管理されてきましたが、関連する変数や関数は1つのオブジェクト内で宣言してまとめてしまうことで、管理しやすくするのがオブジェクト指向。

ブジェクト(object)は、日本語に訳すと、物体。

クラスに含める変数のことは プロパティ 、クラスに含める関数のことは メソッド とも言います。

オブジェクト指向プログラミングとは、積極的にオブジェクトという概念を導入したプログラミング手法ということ。オブジェクト指向プログラミングができるプログラミング言語をオブジェクト指向プログラミング言語。

多くのプログラミング言語がオブジェクト指向を採用。PHP をはじめ、 Java, Ruby, C++, C#, Swift といったプログラミング言語は全てオブジェクト指向プログラミング言語。更に言うと、クラスベースのオブジェクト指向プログラミング言語。

クラスベースのオブジェクト指向では、オブジェクトには クラス と インスタンス という2つの側面があります。

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

論理演算子

&&  条件A && 条件B 条件Aと条件Bがどちらもtrueならばtrueを返す
||   条件A || 条件B 条件Aと条件Bのどちらかがtrueならばtrueを返す
!   !条件A 条件Aがfalseならtrueを返す

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

比較演算子

== 右辺と左辺が等しい場合にはtrueを返す。等しくない場合にはfalseを返す。

!= 右辺と左辺が等しくない場合にはtrueを返す。等しい場合にはfalseを返す。

< 右辺より左辺が小さい場合にはtrueを返す。右辺より左辺が大きいか等しい場合にはfalseを返す。

> 右辺より左辺が大きい場合にはtrueを返す。右辺より左辺が小さいか等しい場合にはfalseを返す。

<= 右辺より左辺が小さいか等しい場合にはtrueを返す。

>= 右辺より左辺が大きいか等しい場合にはtrueを返す。

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

バリデーション

バリデーション 【 validation 】

バリデーションとは、検証、実証、認可、妥当性確認などの意味を持つ英単語。ITの分野では、対象がその仕様や文法などに照らして適切に記述・構築されているか否かを検証するという意味で用いられることが多い。

プログラムのバリデーションといった場合、記述に用いた言語の文法や、そのプログラムに要求される仕様(書の記述)に則って正しく記述されているかを検証することを表す。

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

xamppでCSV(TSV)がうまく読み込めないとき

xamppでCSVやTSVを読み込んでMySQLに登録するバッチを書きました。
PCが故障したのでxamppを入れ替えたらなぜか動かなくなりました。
(一部の行で区切り文字がうまく判定できていない?)

xamppのバージョンかPHPのバージョンか原因はわかりませんが、解決しました。

こちらの記事を参考にさせていただきました。
Windows版php-7.1 で UTF8 の CSV をパースする

setlocale(LC_CTYPE, 'C');
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel Collective

Laravel のFormファサードを使うと、HTML のフォームタグがすっきり。

Composer で「Laravel Collective」パッケージをインストール。
$ composer require "laravelcollective/html":"6.*"

Formファサードの引数
第一引数:name属性の値
第二引数:value属性の値
第三引数:「class」「placeholder」など追加の属性

HTML
input type="text" class="form-control" id="lastName" placeholder="名字">

Formファサード
{{Form::text('lastName', null, ['class' => 'form-control', 'id' => 'lastName', 'placeholder' => '名字'])}}

HTML
form method="POST" action="http://localhost" accept-charset="UTF-8" enctype="multipart/form-data">

Formファサード
{{Form::open(['url' => '/', 'files' => true])}}

HTML
/form>
Formファサード
{{Form::close()}}

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

CRUD

CRUDとは、データベース管理システム(DBRS)に必要とされる4つの主要な機能、「作成(Create)」「読み出し(Read)」「更新(Update)」「削除(Delete)」をそれぞれ頭文字で表したもののことである。

例えばSQLにおいては、「作成」に「INSERT」のコマンドが、「読み出し」に「SELECT」、「更新」に「UPDATE」、「削除」には「DELETE」のコマンドがそれぞれ対応している。CRUDのそれぞれの機能を網羅していることは、データベースシステムの完全性を備えるために必須の要素であるとされている。

フルスペル:Create, Read, Update, Delete
読み方:クラッド

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

マイグレーションとは

マイグレーション機能では、テーブルを新規に作成するためのマイグレーションファイルと呼ばれるファイルを作成して、マイグレーションを実行することで、マイグレーションファイルに書かれたテーブルの定義がMySQLなどのデータベースに間接的に反映される。

例えば、既存のテーブルに、後からカラムを追加したい場合には、カラムを追加するための別のマイグレーションファイルを新たに作成して実行することで、テーブルの定義を変更していく。

マイグレーション機能を使って、テーブル定義を修正すれば、履歴がマイグレーションファイルという形で残っていく。テーブル定義に変更や追加がある度に、新しくマイグレーションファイルを追加作成する。

マイグレーションファイルをある地点まで戻すことを ロールバックという。

$ php artisan make:migration create_???_table --create=???

$ php artisan migrate

$php artisan make:model Message

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

Eclipseでリモートデバッグ Xdebug起動時78%で止まるの巻

開発環境をVagrantへ統一したのは良いが、環境面で色々とつまりまくります。
今回はEclipseでXdebug環境を構築していざリモートデバッグ開始

開発環境

OS:Mac OSX 10.14.6
仮想環境:Vagrant + CentOS 7
PHP:7.3.26
Eclipse : Version: 2020-12 (4.18)

Xdebug開始時に78%で止まる現象

Eclipseのリモートデバッグ構成を作成して、デバッガーはXdebugを設定してこんな感じにする。
名称未設定.png

デバッグスタートすると78%で止まる・・・
スクリーンショット 2021-01-09 19.42.52.png

phpinfoを出すと/etc/php.d/15-xdebug.ini の確認ができたのでXdebug自体は入っている。
スクリーンショット 2021-01-09 19.44.34.png

php.iniの設定も確認します。

[xdebug]
 zend_extension=xdebug.so
 xdebug.remote_enable=1
 xdebug.remote_mode=req
 xdebug.remote_host=[REMOTE_ADDR]

自分の環境に最適なXdebugを調べる https://xdebug.org/wizard
上記のページに行って、下のように出力したphpinfoのソースを貼り付けて調べる
スクリーンショット 2021-01-09 19.45.31.png

スクリーンショット 2021-01-09 19.45.11.png
ほぉ。。。どうやらXdebug3.0を使いなさいと(^^;;

Instructions 通りにxdebug3.0をインストールします。
xdebug3.0 の設定は2.0と少し違うので気をつけて下さい。

/etc/php.ini の最下部に以下を追加

[Xdebug]
zend_extension=/usr/lib64/php/modules/xdebug.so
xdebug.mode = debug
xdebug.client_host = [REMOTE_ADDR]

[REMOTE_ADDR] はVagrant(ゲストOS)へアクセスするホストOSのアドレスです。
適当なPHPファイルを作ってecho $_SERVER['REMOTE_ADDR']; で確認できます。

デフォルトの接続ポートも9000から9003に変更されていますので変更します。
スクリーンショット 2021-01-09 23.20.50.png
スクリーンショット 2021-01-09 22.38.15.png
動いた〜〜!!

自分の環境で、Xdebug開始して78%で止まる現象はXdebugのバージョンでした。
環境によってバージョンではない場合もあるのでご参考までに。

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