かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

Docker nginx + PHP7 + MySQL8 で Laravel 触れる環境つくってみた

構成

/-- docker-compose.yaml
 |- /docker
 |    |- /php
 |    |- /nginx
 |    |- /mysql
 |        |- /data # MySQLのデータの永続化
 |- /laravel # Laravel アプリがインストールされるディレクトリ

使い方

  1. https://github.com/KiKiKi-KiKi/docker-laravel からコードをDLして展開する。
  2. 展開したディレクトリ内に入って下記コマンドを実行
$ cp .env.sample .env
$ make create-project

docker-conpose の build とlaravel のインストールをが完了したら localhost:80 にアクセスして Laravel が動作していれば OK!
🐳 いちねんせい なので、もっとココこうした方が良いがあれば教えて下さい!

₍ ᐢ. ̫ .ᐢ ₎ おわり

make create-project の内容
$ mkdir laravel
$ docker-compose build
$ docker-compose up -d
$ docker-compose exec app composer create-project --prefer-dist laravel/laravel .
$ docker-compose exec app chmod -R 777 storage bootstrap/cache

Laravel のバージョンを指定したい場合は下記のコマンドを使えばOK
e.g. v6 系をインストール

$ docker-compose exec app composer create-project 6.* --prefer-dist laravel/laravel .

[参考]

PHPフレームワーク Laravel入門 第2版

PHPフレームワーク Laravel入門 第2版

海の生き物の抱き枕…KAWAII (ᐡ o̴̶̷̤ ﻌ o̴̶̷̤ ᐡ)

React axios でファイルアップロードしたい

フロントを React バックエンドを PHP で作成していて、ファイルのアップロードを試してみたのでメモ

File を扱うコンポーネント

React では、<input type="file" /> は値がユーザだけが設定できるものでありプログラムでは操作できないため、常に非制御コンポーネントです。
cf. 非制御コンポーネント – React

input[type="file"]value はプログラムで設定できないので値は FileAPI を使って取得する必要があるトノコト。

input[type="file"]value は設定できないけど、onChange で選択されたファイルについては files[0] で取得できる Fileオブジェクト を state として持つことはできるっぽい

function InputFile() {
  const [file, setFile] = useState(null);
  
  const onChangeHandler = useCallback((e) => {
    // ファイル選択がキャンセルされた時は undefined
    const file = e.target.files[0];
    setFile(() => {
      return file ? file : null;
    });
  }, []);

  return <input type="file" accept="image/*" onChange={onChangeHandler} />
}

state でファイルオブジェクトを持ってしまうので、公式リファレンスにあるように useRef を使って必要なときだけ ファイルオブジェクトを取り出すようにした方がメモリ効率は良いのかも知れない。

File を含むデータを axios で送信する

以前書いた記事 JavaScript (SPA) PHP axios でフォームデータを送る時に気をつけること - かもメモ でバックエンドの PHP$_POST でフォームデータを取得できるようにするには URLSearchParams 形式で送れば OK と書いていたのですが、URLSearchParams で送った場合 $_FILESnull になってしまいうまく取得できませんでした。

ファイルを含むフォームデータは FormData 形式の Content-Type: 'multipart/form-data' で送るのが良いみたいです。

フロント

function PostForm() {
  const ref = useRef(null);

  const onPostForm = useCallback(async(data) => {
    try {
      // Object の data を FormData 形式に変換する
      const params = new FormData();
      Object.keys(data).forEach(function(key) {
        params.append(key, this[key]);
      }, data);
      const res = await axios.post(API_URL, params, {
        headers: {
          'Content-Type': 'multipart/form-data',
        },
      });
      console.log(res);
    } catch(err) {
      console.log(err);
    }
  }, []);
  
  const onSubmitHandler = useCallback((e) => {
    e.preventDefault();
    onPostForm({
      file: ref.current.files[0],
    });
  }, [onPostForm]);

  return (
    <form onSubmit={onSubmitHandler}>
      <input type="file" accept="image/*" ref={ref} />
      {/* 略 */}
    </form>
  );
}

バックエンド (PHP)

<?php
$file = $_FILES['file'];

header('Content-Type: application/json; charset=utf-8', true, 200);
echo json_encode([
  'file_name' => $file['name'],
  'tmp_file' => $file['tmp_name'],
  'error' => $file['error'],
], JSON_UNESCAPED_UNICODE);

FormData 形式・Content-Type: 'multipart/form-data' で送信すれば PHP$_FILES で送られたファイルデータを取得することができました!
₍ ᐢ. ̫ .ᐢ ₎ ヤッタネ!!


[参考]

Ruby bundle install gb のエラーにハマる

Rails のプロジェクトのローカル環境を作っていて bundle install したら pg の箇所でエラーが発生したのでメモ

環境

エラー内容

$ bundle install
# … 略
Installing pg 1.2.3 with native extension
checking for pg_config... no
No pg_config... trying anyway. If building fails, please try again with
 --with-pg-config=/path/to/pg_config
checking for libpq-fe.h... no
Can't find the 'libpq-fe.h header
\*\*\* extconf.rb failed \*\*\*
# … 略
An error occurred while installing pg (1.2.3), and Bundler cannot
continue.
Make sure that `gem install pg -v '1.2.3' --source 'https://rubygems.org/'`
succeeds before bundling.

In Gemfile:
  pg

pg_config のパスを指定する

pg_config が見つからないので、 --with-pg-config=/path/to/pg_config オプションで pg_config のパスを指定しろトノコト
homebrew でインストールした postgresql の bin 内に pg_config があるのでこのパスを指定する

/usr/local/Cellar/postgresql/<VWESION>/bin/pg_config

こんな感じ。

$ bundle config build.pg --with-pg-config=/usr/local/Cellar/postgresql/<VWESION>/bin/pg_config
$ bundle install
// …略
Installing pg 1.2.3 with native extension
checking for libpq-fe.h... no
Can't find the 'libpq-fe.h header
\*\*\* extconf.rb failed \*\*\*
// …略

libpq-fe.h が無いというエラーが出続けている…

libpqpg_config を指定する

$ brew install libpq

libpq
You can install libpq (dev files are included) alone using homebrew.
cf. postgresql - Install libpq-dev on Mac OS? - Super User

Postgres 無しに devファイルを含む psql などのユーティリティを提供しているパッケージらしい
libpq にも pg_config があるのでこちらのファイルを指定してみる

/usr/local/Cellar/libpq/<VWESION>/bin/pg_config

パスは postgresql と同じ感じ

$ bundle config build.pg --with-pg-config=/usr/local/Cellar/libpq/VWESION/bin/pg_config
$ bundle install
// …略
Installing pg 1.2.3 with native extensions
// ...略

問題なく bundle install が完了しました。
このまま問題なくローカル環境は動作しているのですが、postgresql もインストールしている状態だったので libpq だけで十分なのかどうかは解っていません。
bundle install gb でコケて postgresqlpg_config のパスを指定してもうまく行かない場合は libpg を使うと解決するかも知れません。

Ruby まだ慣れてないのでエラーとかがなんもわからん状態です。
おわり


[参考]