PHP

Laravel Sailに追加したPhpMyAdminからデータベースにつながらない

先日、Laravel Sailについて質問を受けた内容です。

PhpMyAdminを使いたいということで、自身で調べてdocker-composeにサービスの追加をしたけど、動かないということでした。

Sail を起動して、ブラウザでPhpMyAdminにログインしようとすると、エラーになってしまいます。

ログインの時点でエラー

とりあえずMySQLの疎通確認から。

Laravelコンテナからマイグレーションの実行はできているので、MySQLコンテナ自体はちゃんと動いているようです。

$ sail artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (553.47ms)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (767.61ms)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated:  2019_08_19_000000_create_failed_jobs_table (589.25ms)
Migrating: 2019_12_14_000001_create_personal_access_tokens_table
Migrated:  2019_12_14_000001_create_personal_access_tokens_table (380.02ms)

コンテナ起動時にも、ちゃんとphpmyadminコンテナが起動してます。

$ sail up -d
Creating network "laraveltest_phpmyadmin_sail" with driver "bridge"
Creating laraveltest_phpmyadmin_mailhog_1     ... done
Creating laraveltest_phpmyadmin_redis_1       ... done
Creating laraveltest_phpmyadmin_mysql_1       ... done
Creating laraveltest_phpmyadmin_selenium_1    ... done
Creating laraveltest_phpmyadmin_meilisearch_1 ... done
Creating laraveltest_phpmyadmin_phpmyadmin_1   ... done
Creating laraveltest_phpmyadmin_laravel.test_1 ... done

$ sail ps
                Name                               Command                  State                           Ports
--------------------------------------------------------------------------------------------------------------------------------------
laraveltest_phpmyadmin_laravel.test_1   start-container                  Up             0.0.0.0:80->80/tcp, 8000/tcp
laraveltest_phpmyadmin_mailhog_1        MailHog                          Up             0.0.0.0:1025->1025/tcp, 0.0.0.0:8025->8025/tcp
laraveltest_phpmyadmin_meilisearch_1    tini -- /bin/sh -c ./meili ...   Up (healthy)   0.0.0.0:7700->7700/tcp
laraveltest_phpmyadmin_mysql_1          /entrypoint.sh mysqld            Up (healthy)   0.0.0.0:3306->3306/tcp, 33060/tcp, 33061/tcp
laraveltest_phpmyadmin_phpmyadmin_1     /docker-entrypoint.sh apac ...   Up             0.0.0.0:8080->80/tcp
laraveltest_phpmyadmin_redis_1          docker-entrypoint.sh redis ...   Up (healthy)   0.0.0.0:6379->6379/tcp
laraveltest_phpmyadmin_selenium_1       /opt/bin/entry_point.sh          Up             4444/tcp, 5900/tcp

Laravel本体のコンテナとMySQLのコンテナは疎通してて、PhpMyAdminからだとつながってないような状況なので、コンテナ内でなんか起こってるのかなと目星をつけました。

ご質問者さんに了解を取ったうえで、ボリュームを削除して作り直してみます。

sail down --volumes --remove-orphans
Stopping laraveltest_phpmyadmin_laravel.test_1 ... done
Stopping laraveltest_phpmyadmin_phpmyadmin_1   ... done
Stopping laraveltest_phpmyadmin_meilisearch_1  ... done
Stopping laraveltest_phpmyadmin_selenium_1     ... done
Stopping laraveltest_phpmyadmin_mysql_1        ... done
Stopping laraveltest_phpmyadmin_redis_1        ... done
Stopping laraveltest_phpmyadmin_mailhog_1      ... done
Removing laraveltest_phpmyadmin_laravel.test_1 ... done
Removing laraveltest_phpmyadmin_phpmyadmin_1   ... done
Removing laraveltest_phpmyadmin_meilisearch_1  ... done
Removing laraveltest_phpmyadmin_selenium_1     ... done
Removing laraveltest_phpmyadmin_mysql_1        ... done
Removing laraveltest_phpmyadmin_redis_1        ... done
Removing laraveltest_phpmyadmin_mailhog_1      ... done
Removing network laraveltest_phpmyadmin_sail
Removing volume laraveltest_phpmyadmin_sail-mysql
Removing volume laraveltest_phpmyadmin_sail-redis
Removing volume laraveltest_phpmyadmin_sail-meilisearch

これで直りました。どういう事象でエラーだったのかわからないけど。。。

ボリュームを消しちゃったので、MySQLも空っぽになっています。

このあと、マイグレーション・シーディングをし直してもらいました。

以上です。あなたのお役に立てれば幸いです。

Laravel Sail でコンテナのshellを使う

こんばんは、ウチイダです。

Laravel Sail便利ですよね。docker-compose のラッパーみたいなものなので、学習コストも低くてとても良い感じです。

docker-composeでできることは何でもできるので、困ったらdocker-composeのコマンドを調べるのですが、なかなか覚えられません。

ちょくちょく使うのが、コンテナに入るコマンドです。

# Laravelアプリケーションのコンテナのbashを開く
$ docker-compose exec laravel.test bash

dockerコマンドみたいに、-it とかオプション付けなくてもいいので、まだいいですが、長いですよね。

あるときふとReadoubleを見直してみたら、sail コマンドからコンテナ接続するサブコマンドがちゃんと用意されていました。

# sail コマンドから、Laravel アプリケーソンのコンテナのbashをひらく
$ sail shell

# root ユーザーで接続する場合
$ sail root-shell

# Readoubleにはないけど、以下でもOK
$ sail bash

すごく短くなります。

sailコマンドの中身(vendor/bin/bash)は難しくないshellスクリプトなので、中身を見てみるといろいろ発見があって面白いです。

以上です。あなたのお役に立てれば幸いです。

phpbrewで、mcryptバリアントがインストールできない

こんにちは、ウチイダです。

最近またPHPを触ることが増えてきていて、Windows11のWSL2上にphpbrewで環境構築をしています。

今回はmcryptを使いたくなり、バリアントを追加しようとしたらうまくいかなかったというトラブルです。

バリアントをインストールしようとしたら、以下のようなエラーが。

$ phpbrew ext install mcrypt
Downloading https://pecl.php.net/rest/r/mcrypt/stable.txt via curl extension
[==================================================================] 5.00/5.00B 100%
Downloading https://pecl.php.net/rest/r/mcrypt/1.0.4.xml via curl extension
[==================================================================] 736.00/736.00B 100%
Downloading https://pecl.php.net/rest/r/mcrypt/stable.txt via curl extension
[==================================================================] 5.00/5.00B 100%
Downloading https://pecl.php.net/rest/r/mcrypt/1.0.4.xml via curl extension
[==================================================================] 736.00/736.00B 100%
Downloading https://pecl.php.net/get/mcrypt-1.0.4.tgz via curl extension
[==================================================================] 26.42/26.42KB 100%
===> Extracting to /home/y-uchiida/.phpbrew/build/php-7.4.23/ext...
===> Installing mcrypt extension...
Log stored at: /home/y-uchiida/.phpbrew/build/php-7.4.23/ext/mcrypt/build.log
Changing directory to /home/y-uchiida/.phpbrew/build/php-7.4.23/ext/mcrypt
===> Phpize...
Error: Command failed: phpize > /home/y-uchiida/.phpbrew/build/php-7.4.23/ext/mcrypt/build.log 2>&1 returns:

調べてみたところ、どうやらautoconfのパッケージが入ってなかったり、バージョンが古いと、phpizeでエラーするみたいです。

とりあえずautoconfをインストールします。

$ sudo apt install autoconf

再度バリアントのインストールを試みると、今度は別のエラーが出ました。

$ phpbrew ext install mcrypt
[ ] mcrypt extension is disabled.
===> Installing mcrypt extension...
Log stored at: /home/y-uchiida/.phpbrew/build/php-7.4.23/ext/mcrypt/build.log
Changing directory to /home/y-uchiida/.phpbrew/build/php-7.4.23/ext/mcrypt
===> Running make clean: /usr/bin/make -C '/home/y-uchiida/.phpbrew/build/php-7.4.23/ext/mcrypt' --quiet 'clean'
===> Phpize...
===> Configuring...
Error: Command failed: ./configure '--with-php-config=/home/y-uchiida/.phpbrew/php/php-7.4.23/bin/php-config' >> '/home/y-uchiida/.phpbrew/build/php-7.4.23/ext/mcrypt/build.log' 2>&1 returns:

調べてみたけど、よくわかりませんでした…

ふと、バリアントは、パッケージの本体がないとインストールできないという仕様に思い至りました。

WSLのほうでmcryptのパッケージを入れてなかったような気がしたので、インストール。

$ sudo apt-get install libmcrypt-dev
# ...(中略)...
The following NEW packages will be installed:
  libmcrypt-dev

やっぱり入ってませんでした。

再度、mcrypt バリアントをインストールします。

$ phpbrew ext install mcrypt
[ ] mcrypt extension is already disabled.
===> Installing mcrypt extension...
# ...(中略)...
[*] mcrypt extension is enabled.
Done.

今度はうまくいったみたいです。

最後に、phpbrewで管理しているPHPに、バリアントを追加します。

$ phpbrew install 7.4.20 +mcrypt
===> phpbrew will now build 7.4.20
===> Loading and resolving variants...
# ...(中略)...
Congratulations! Now you have PHP with 7.4.20 as php-7.4.20

* To configure your installed PHP further, you can edit the config file at
    /home/y-uchiida/.phpbrew/php/php-7.4.20/etc/php.ini

To use the newly built PHP, try the line(s) below:

    $ phpbrew use php-7.4.20

Or you can use switch command to switch your default php to php-7.4.20:

    $ phpbrew switch php-7.4.20

Enjoy!

ビルドしなおしなので、結構時間かかります。

phpinfo を見てみると、mcryptの項目が増えていることが確認できました。

まとめ

今回必要だったのは、以下のコマンドを実行することでした。

  • autoconf パッケージのインストール( sudo apt install autoconf )
  • mcyrpt パッケージのインストール( sudo apt-get install libmcrypt-dev )
  • mcrypt バリアントを含めて、phpbrewで再ビルド(sudo phpbrew install 7.4.20 +mcrypt)

以上です。

あなたのお役に立てたらうれしいです。

WSL上のDocker Composeで作成したコンテナに、Windows 11ホストから接続する

こんにちは、ウチイダです。

ここしばらく、Windwos 11のWSL Ubuntu での環境構築を進めてきました。

前回の記事で、Docker Composeのインストールを紹介しています。

今回はその続きとして、シンプルなPHP開発環境をDocker Compose を用いて作成し、Windows ホストのブラウザからアクセスできるように設定していきます。

これができると、ついにWindows 11でWSLを使った実用的なWeb開発ができるようになります。

なお、動作環境は以下の通りです。

  • Windwos 11 Pro (21H2 ビルド 22000.120)
  • WSL カーネル バージョン: 5.10.16
  • Windows Terminal バージョン: 1.9.1942.0
  • Docker バージョン 20.10.8, build 3967b7d
  • Docker Compose バージョン 1.29.2, build 5becea4c

前準備①:Docker デーモンを起動する

WSLのディストリビューションは、サービスの自動起動などを行いません。

WSLを起動した後、最初にDockerを利用する場合は、デーモンを起動するのを忘れないようにしましょう。

$ sudo service docker start
[sudo] password for y-uchiida:
 * Starting Docker: docker                                 [ OK ]

## Docker デーモンの起動を確認します
$ service docker status
 * Docker is running

前準備②:開発環境をつくるディレクトリを作成

続いて、Docker に関するファイルや、PHPなどのスクリプトを置くディレクトリを作成します。

例として、「sample_docker-compose_on_wsl」を作成します。

また、PHPやJavaScriptなどのデータを置くための「public」も作成しておきます。

## とりあえずホームディレクトリに作ることにします
## 開発環境をまとめておく場所を決めている方は、そちらに作成してください
$ mkdir ~/sample_docker-compose_on_wsl

## 公開用ファイルを設置するpublic ディレクトリを作成します
$ mkdir ~/sample_docker-compose_on_wsl/public 

前準備③:ファイル編集とDocker実行の準備

この後の作業で、yamlファイルを編集したりdocker-compose コマンドを実行したりするので、作成した開発環境用のディレクトリに移動しておきます。

また、エディタも用意します。以下の例では、VS Codeでsample_docker-compose_on_wsl ディレクトリを開いています。

## docker-compose コマンドを使うので、カレントディレクトリを移動しておきます
$ cd ~/sample_docker-compose_on_wsl

## Visual Studio Code(VS Code) を利用している方は、code コマンドでVS Codeで開くことができます
## docker-compose.ymlの編集などはVS Code
$ code .

docker-compose.ymlを作成する

準備が整いましたので、Docker Compose でコンテナを生成・起動するためのファイル docker-compose.ymlを作っていきます。

sample_docker-compose_on_wsl ディレクトリ配下に作成します。

完成コードは以下です。

ディスク容量を圧迫しないように、alpine ベースのイメージを選択しました。

version: '3.8' # 現時点での最新のバージョンを指定しておきます
services: 

  # Webサーバとして、nginx を利用します
  web: 
    container_name: "web"
    image: nginx:1.21.1-alpine
    ports:
      - "8080:80" # ポート8080を、ポート80 へフォワーディングします
    links:
      - app # php 実行コンテナ(app)に接続できるようにします
    volumes:
      - ./public:/var/www/public # WSL側のpublic ディレクトリを、web コンテナにマウントします
      - ./default.conf:/etc/nginx/conf.d/default.conf # nginx の設定ファイルを、web コンテナにマウントします

  app:
    container_name: "app"
    image: php:7.4-fpm-alpine3.14
    volumes:
      - ./public:/var/www/public # web コンテナと同じパスにアクセスできるように、app コンテナにもpublic ディレクトリをマウントします

ここでのポイントは2点あります。

ひとつは、links でweb コンテナから app コンテナに接続できるように設定したことです。

これにより、phpファイルが呼び出された際にapp コンテナへ処理を引き渡すことができるようになります。

もうひとつは、web と app の両方の volumes に./publicをマウントするように記述したことです。

同じファイルパスで参照できるようになるので、スムーズに処理の引き渡しができます。

コンテナにマウントするファイルを作成する

続いて、コンテナにマウントするファイルを作っていきます。

最低限の用意として、2つのファイルを作成します。

phpの処理をapp コンテナに引き渡すための設定を記述したnginxのconfigファイル「default.conf」と、publicルートにアクセスした際に処理される「index.php」です。

default.confの作成

まずは、nginxの設定ファイルから見ていきます。

sample_docker-compose_on_wsl ディレクトリの直下に、以下のdefault.conf を作成してください。

server {
    listen 80;
    server_name localhost;

    root /var/www/public;
    index index.php;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    # PHP ファイルへアクセスされた場合に、app コンテナのfast CGIへ処理を回します
    location ~ \.php$ {
        include fastcgi_params;

        # app コンテナのポート9000でFast CGI がListenしているので、そちらへパスします
        fastcgi_pass app:9000;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_index index.php;

        # nginx がアクセスされたファイルパスを、app コンテナで処理すべきファイルパスとして渡します
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;

        try_files $uri = 404;
    }
}

ポイントは、 location ~ \.php のディレクティブです。

ここで、php ファイルにアクセスされた際にapp コンテナへ処理を移すための設定を記載しています。

app コンテナのポート9000でFast CGI がListenしているので、fastcgi_pass はapp:9000 を指定します。

また、SCRIPT_FILENAME で、nginx がアクセスされたファイルパス($dcoument_root$fastcgi_script_name)を渡しています。

docker-compose.yml では、2つのコンテナにpublic ディレクトリを同じパスにマウントしました。

コンテナ同士のphpファイルのパスを一致させているため、このように記述できます。

index.php の作成

最後に、index.php を作成します。

これは、phpが動作していることが分かれば何でもよいです。

public ディレクトリ内に作成します。

<?php
    echo "hello from docker on wsl!!<br>\r\n";

内容は、好きなように設定してください。

コンテナの起動と動作確認

準備が整いましたので、docker コンテナを起動して動作を見ていきます。

まずはコンテナの起動です。

## dockerコンテナの起動には、sudo が必要になると思います
## コンテナ起動後にほかのコマンドを使いたいので、最後に & をつけてバックグラウンドで処理させます
$ sudo docker-compose up &
Creating app ... done
Creating web ... done
Attaching to app, web
app    | [09-Aug-2021 09:19:39] NOTICE: fpm is running, pid 1
app    | [09-Aug-2021 09:19:39] NOTICE: ready to handle connections
web    | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
web    | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
web    | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
web    | 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
web    | 10-listen-on-ipv6-by-default.sh: info: /etc/nginx/conf.d/default.conf differs from the packaged version
web    | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
web    | /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
web    | /docker-entrypoint.sh: Configuration complete; ready for start up
web    | 2021/08/09 09:19:40 [notice] 1#1: using the "epoll" event method
web    | 2021/08/09 09:19:40 [notice] 1#1: nginx/1.21.1
web    | 2021/08/09 09:19:40 [notice] 1#1: built by gcc 10.3.1 20210424 (Alpine 10.3.1_git20210424)
web    | 2021/08/09 09:19:40 [notice] 1#1: OS: Linux 5.10.16.3-microsoft-standard-WSL2
web    | 2021/08/09 09:19:40 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
web    | 2021/08/09 09:19:40 [notice] 1#1: start worker processes
web    | 2021/08/09 09:19:40 [notice] 1#1: start worker process 32
web    | 2021/08/09 09:19:40 [notice] 1#1: start worker process 33
web    | 2021/08/09 09:19:40 [notice] 1#1: start worker process 34
web    | 2021/08/09 09:19:40 [notice] 1#1: start worker process 35

コンテナ起動時のメッセージがたくさん出ます。最後にstart worker process (番号) と表示されれば成功です。

コンテナの起動コマンドの最後に 「&」 をつけておくと、コンテナの起動がバックグラウンドで処理されます。

バックグラウンド処理にしておくことで、up コマンド実行後も同じターミナルで別のコマンドが実行できます。

WSLからコンテナにアクセス

まずはDocker コンテナのホストであるWSL から、コンテナへアクセスしてみます。

8080ポートをフォワーディングしているので、localhost:8080でコンテナ内のnginxへアクセスできます。

curl コマンドを用いて、レスポンスを確認します。

$ curl http://localhost:8080/
hello from docker on wsl!!<br>
app    | 172.22.0.3 -  09/Aug/2021:10:07:27 +0000 "GET /index.php" 200
web    | 172.22.0.1 - - [09/Aug/2021:10:07:27 +0000] "GET / HTTP/1.1" 200 43 "-" "curl/7.68.0"

index.php でechoした文字列「hello from docker on wsl!!」が表示されています。

また、web コンテナ、app コンテナそれぞれがメッセージを出してきました。

このような表示になれば、うまく設定できています。

index.php の内容を変更・保存し、再度curl コマンドを実行すると、表示内容が変わります。

Windows ホストのブラウザからコンテナにアクセス

最後に、Windows上のブラウザからコンテナにアクセスしてみます。

以前はWindows ホストからWSLにアクセスするには設定が必要だったのですが、今ではとくに何もしなくてもよいようです。

ブラウザを開き、localhost:8080にアクセスしてみます。

あっさり接続できてしまいました。

WSLのDockerで、こんなに簡単にPHP開発環境が作れるとは驚きです。

Docker コンテナを終了する

一通り動作確認をしたら、Docker コンテナを終了します。

$ sudo docker-compose down
Stopping web ...
Stopping app ...
web    | 2021/08/09 10:45:04 [notice] 1#1: signal 3 (SIGQUIT) received, shutting down
web    | 2021/08/09 10:45:04 [notice] 33#33: gracefully shutting down
web    | 2021/08/09 10:45:04 [notice] 34#34: gracefully shutting down

... 中略 ...

Removing web ... done
Removing app ... done
Removing network sample_docker-compose_default
[1]+  Done                    sudo docker-compose up

またコンテナにアクセスしたい場合は、 docker-compose up を実行してください。

まとめ:WSLでも、スムーズにPHP開発環境が構築できるようになりました

今回はこれで終了です。

2021年8月時点では、とても簡単にWSLを使ったPHP開発環境が構築できるようになっていました。感動。

Docker Compose を使いたかったので長くなってしまいましたが、Windows ホストからWSL 上のDocker コンテナにつなげるだけだったら、もっと簡単にできそうです。

PHP のほかにも、node.js やPython の環境も、同じ要領で構築できそうです。

ここから先はDocker の領域に入っていきますので、Docker に関する情報などをあたってみるとよいかと思います。

以上、あなたのお役に立てれば幸いです。

phpbrew からインストールしたPHPでartisan migrae できない

プロジェクトごとにPHPのバージョン管理をするため、先日、phpbrewを導入しました。

しばらくは問題なく使えていたのですが、Laravelの開発のためartisanコマンドを実行したときにエラーが。

$ php artisan migrate

   Illuminate\Database\QueryException  : could not find driver (SQL: select * from information_schema.tables where table_schema = laravel_chap5 and table_name = migrations and table_type = 'BASE TABLE')

  at /var/www/public/laravel_app/vendor/laravel/framework/src/Illuminate/Database/Connection.php:669
    665|         // If an exception occurs when attempting to run a query, we'll format the error
    666|         // message to include the bindings with SQL, which will make this exception a
    667|         // lot more helpful to the developer instead of just the database's errors.
    668|         catch (Exception $e) {
  > 669|             throw new QueryException(
    670|                 $query, $this->prepareBindings($bindings), $e
    671|             );
    672|         }
    673|

  Exception trace:

  1   PDOException::("could not find driver")
      /var/www/public/laravel_app/vendor/laravel/framework/src/Illuminate/Database/Connectors/Connector.php:70

  2   PDO::__construct("mysql:host=localhost;port=3306;dbname=laravel_app", "laravel_user", "laravel_passwd", [])
      /var/www/public/laravel_app/vendor/laravel/framework/src/Illuminate/Database/Connectors/Connector.php:70

  Please use the argument -v to see more details.

PDOExeption::(“coult not find driver”) となってます。PDOドライバーがない??

phpのインストール状況を見てみました。

$ php -i | grep PDO
PDO
PDO support => enabled
PDO drivers =>

むむ…。確かに設定されていない…

defaultバリアントにもpdoは含まれているんですけどね…念のためインストールしなおし。

$ phpbrew install 7.4.21 +default +pdo +mysql
===> phpbrew will now build 7.4.21
===> Loading and resolving variants...
Checking distribution checksum...
Checksum matched: 36ec6102e757e2c2b7742057a700bbff77c76fa0ccbe9c860398c3d24e32822a
===> Distribution file was successfully extracted, skipping...

# 中略 #

* We found that you enabled 'mysql' variant, you might need to setup your
  'pdo_mysql.default_socket' or 'mysqli.default_socket' in your php.ini file.

* To configure your installed PHP further, you can edit the config file at
    /home/uchiida/.phpbrew/php/php-7.4.21/etc/php.ini

To use the newly built PHP, try the line(s) below:

    $ phpbrew use php-7.4.21

Or you can use switch command to switch your default php to php-7.4.21:

    $ phpbrew switch php-7.4.21

Enjoy!

バリアントをつけなおしてみても、状況は変わらず。うーんなんなのか…

メッセージをよく見てみると、「mysqlバリアントを有効にするには、php.iniでソケットをセットアップする必要があるかもよ」と書かれています。

改めてGithubのREADMEを見直してみたところ、phpbrew config でiniを修正することができると書いてあります。

https://github.com/phpbrew/phpbrew/blob/master/README.ja.md#extention-installer

記載の通りにコマンド入力したら、エディタが立ち上がったので、そのまま保存して終了しました。

これで直ったのかな~と思いつつ、PHPの情報を見てみると、、、

$ php -i | grep PDO
PDO
PDO support => enabled
PDO drivers => mysql
PDO Driver for MySQL => enabled

直ってました。artisan migrate コマンドも実行できました。

iniファイルの変更は、別途行わないといけないみたいですね…

以上です。あなたのお役に立てればうれしいです。

Laravel 6 にlaravel/ui をインストールしたらエラー

Laravel 6で新規プロジェクトを立ち上げて、composerでlaravel/uiをインストールしようとしたらエラーになってしまいました。

$ composer require laravel/ui
Using version ^3.3 for laravel/ui
./composer.json has been updated
Running composer update laravel/ui
Loading composer repositories with package information
Updating dependencies
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - laravel/ui[v3.3.0, ..., 3.x-dev] require illuminate/console ^8.42 -> found illuminate/console[v8.42.0, ..., 8.x-dev] but these were not loaded, likely because it conflicts with another require.
    - Root composer.json requires laravel/ui ^3.3 -> satisfiable by laravel/ui[v3.3.0, 3.x-dev].


Installation failed, reverting ./composer.json and ./composer.lock to their original content.

バージョン要求を満たしてないみたいです。

Laravel 6 の公式ドキュメントを見たら、laravel/uiのバージョンを指定するように記載がありました。

https://laravel.com/docs/6.x/frontend

The Bootstrap and Vue scaffolding provided by Laravel is located in the laravel/ui Composer package, which may be installed using Composer:
composer require laravel/ui:^1.0 –dev

https://laravel.com/docs/6.x/frontend

指定のコマンドで再チャレンジします。

$ composer require laravel/ui:^1.0 --dev
./composer.json has been updated
Running composer update laravel/ui
Loading composer repositories with package information
Updating dependencies
Lock file operations: 1 install, 0 updates, 0 removals
  - Locking laravel/ui (v1.3.0)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
As there is no 'unzip' nor '7z' command installed zip files are being unpacked using the PHP zip extension.
This may cause invalid reports of corrupted archives. Besides, any UNIX permissions (e.g. executable) defined in the archives will be lost.
Installing 'unzip' or '7z' may remediate them.
  - Downloading laravel/ui (v1.3.0)
  - Installing laravel/ui (v1.3.0): Extracting archive
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi
Discovered Package: facade/ignition
Discovered Package: fideloper/proxy
Discovered Package: laravel/tinker
Discovered Package: laravel/ui
Discovered Package: nesbot/carbon
Discovered Package: nunomaduro/collision
Package manifest generated successfully.
67 packages you are using are looking for funding.
Use the `composer fund` command to find out more!

unzipがない、という警告が出てますが、とりあえずインストールはできたみたいです。

bugfixサポートも2021年9月に切れるので、そろそろLaravel6の利用も終えたほうがよさそうですね。

以上です。あなたのお役に立てればうれしいです。

Laravelで存在しないコントローラへのルーティングを書いたらInvalid route action エラーになった

久しぶりにLaravelを触っていて、変なところでつまづいたのでメモしておきます。

発生したのはLaravel 6.20 です。

新しくコントローラを作成しようとして、artisan でmake:controllerを実行したらエラーになりました。

$ php artisan make:controller NewSingleActionController --invokable

   UnexpectedValueException  : Invalid route action: [App\Http\Controllers\NewSingleActionController].

  at /var/www/laravel_app/vendor/laravel/framework/src/Illuminate/Routing/RouteAction.php:92
    88|      */
    89|     protected static function makeInvokable($action)
    90|     {
    91|         if (! method_exists($action, '__invoke')) {
  > 92|             throw new UnexpectedValueException("Invalid route action: [{$action}].");
    93|         }
    94|
    95|         return $action.'@__invoke';
    96|     }

  Exception trace:

  1   Illuminate\Routing\RouteAction::makeInvokable("App\Http\Controllers\NewSingleActionController")
      /var/www/laravel_app/vendor/laravel/framework/src/Illuminate/Routing/RouteAction.php:47

  2   Illuminate\Routing\RouteAction::parse("new_route", ["App\Http\Controllers\NewSingleActionController", "App\Http\Controllers\NewSingleActionController"])
      /var/www/laravel_app/vendor/laravel/framework/src/Illuminate/Routing/Route.php:162

  Please use the argument -v to see more details.

最初はartisanコマンドを間違えたのかと思ったのですが、Execption traceのところをよく見てみると、Route.phpで例外発生しています。

そういえば、この後コントローラを作るからと、NewSingleActionContoller へのルーティングを書いておいたんだった。

web.phpから、NewSingleActionContllerへのルーティング情報をコメントアウトしたら解消しました。

artisanコマンドって、Routeなどの直接関係してなさそうなソースの例外も拾って動作停止するんですね…知らなかった。

こちらのQiita記事を見て、原因に気づいたのですが…名前空間の制御、意識してないとまた忘れそうです。

https://qiita.com/Okkun555/items/3a8c5df75a3f45d0474c

以上です。あなたのお役に立てればうれしいです。

プリペアドステートメントでLIKE検索

つい忘れて何度も悩むんですよね。プリペアドステートメントでLIKEするときの注意点。

PHPでプリペアードステートメントを作るとき、検索ワードをそのままクエリに入れるとうまくいきません。

$word = "a"
$stmt->dbh.prepare("SELECT * FROM fruits WHERE name LIKE '%?%'"); /* これはダメ */
$stmt.execute([$word]);

?に展開されるときに、値をシングルクオートで囲むためのようです。

あらかじめワイルドカードとくっつけておいてから、クエリに渡します。

$word = "%a%" /* 検索文字列に、ワイルドカードを含める */
$stmt->dbh.prepare("SELECT * FROM fruits WHERE name LIKE ?");
$stmt.execute([$word]);

以上です。あなたのお役に立てればうれしいです。