PHPのメモリ上限をアップする方法

エラーメッセージ

Fatal error: Allowed memory size of xxxxxx bytes exhausted

が発生することがある場合の対象方法を説明いたします

初期ではPHPのメモリ上限が少なく設定されています。その際に上記メッセージに遭遇することがあります。
 この場合はPHPのメモリ使用量の上限を変更するのですが、そのときに設定するパラメータがmemory_limitです。

現在使用可能なメモリ使用量の確認

現在PHPに割り当てられているメモリ使用量を確認します。

$ php -i | grep memory_limit

memory_limit => 128M => 128M

memory_limitはphp.iniに設定されています。そのため、読み込まれているphp.iniがどこにあるかパスを確認しましょう。

$ php -i | grep php.ini

Configuration File (php.ini) Path => /path/to/php/etc
Loaded Configuration File => /path/to/php/etc/php.ini

メモリ使用量を任意の値に変更

php.iniのmemory_limitを編集して、割り当てたいメモリ量を設定します。
512MBのメモリを割り当てた場合の設定を次に示します。

memory_limit = 512M

メモリ使用量を無制限に変更する

メモリの使用量を無制限にしたい場合は、memory_limitに”-1″を設定します。。

memory_limit = -1

Laravel ページネーションでも検索条件を引き継ぐコーディングポイント

ページネーションの設定は

{{$data->render()}}

しかし、ページ番号選択で条件が消えます

そこで下記へ変更です

{{$data->appends(request()->input())->render()}}

注意点は、appendsは、パラメータを配列で渡すメソッドなので、検索フォームはGETメソッドでないと上手く動作しない点ですのでお気をつけください

データからseederを生成方法

composer require “orangehill/iseed”

config/app.phpprovidersOrangehill\Iseed\IseedServiceProvider::classを追加

php artisan issed テーブル名

PS C:\Users\user\Documents\MEGA\SOHO\MENTA\src\sales> php artisan iseed basics 
Created a seed file from table basics

こんな感じでseeder が作成できます

便利ですよね。

補足ですが、

外部キーがある場合、\DB::table('table名')->delete();でエラーになったので、\DB::statement('SET FOREIGN_KEY_CHECKS=0');で外部キーチェックを一時的に無効にし、\DB::statement('SET FOREIGN_KEY_CHECKS=1');で有効にすることで回避できます

Laravel環境構築時のDB Connection エラー対処方法

◆エラー内容

PS C:\Users\user\Documents\MEGA\SOHO\MENTA\src\sales> php artisan migrate        

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

  at C:\Users\user\Documents\MEGA\SOHO\MENTA\src\sales\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   Doctrine\DBAL\Driver\PDOException::("could not find driver")
      C:\Users\user\Documents\MEGA\SOHO\MENTA\src\sales\vendor\doctrine\dbal\lib\Doctrine\DBAL\Driver\PDOConnection.php:31

  2   PDOException::("could not find driver")
      C:\Users\user\Documents\MEGA\SOHO\MENTA\src\sales\vendor\doctrine\dbal\lib\Doctrine\DBAL\Driver\PDOConnection.php:27

  Please use the argument -v to see more details.
PS C:\Users\user\Documents\MEGA\SOHO\MENTA\src\sales> 

.envのデータベース名もあっているし、データベースも作成されている。どうもPDOが接続できないようです。

◆原因

php格納場所を where コマンドで確認

C:\Users\user\Documents\MEGA\SOHO\MENTA\src\sales>where php
C:\php\php.exe

cd で 該当ディレクトリで移動し php.ini を開く

phpinfoはブラウザ経由で見ましたが、extension=pdo_mysql (PDO)がPHPで指定されていませんでした

◆対策

php.ini を変更します

extension=pdo_mysql

を生かしましょう

これで無事にマイグレーションできました

Laravel 6 テーブルからマイグレーションファイル作成方法

すでにCREATE TABLEのSQLコマンドを使ったテーブル定義のメンテナンスを依頼されましたが、怖いためマイグレーションファイルを生成してくれるパッケージがありましたので使ってみました(過去も何度もお世話になってます。毎回忘れてしまうので備忘録です)

検証環境

PHP7.3.2
Laravel 6.2

パッケージ名

migrations-generator

手順

composer require --dev "xethron/migrations-generator"
php artisan migrate:generate --ignore="users,password_resets"

※ --ignore は対象から除くテーブルです

マイグレーションでの外部キー削除設定。

新規テーブル時の外部キー作成はOK

public function up()
    {
        Schema::create('categorys', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('user_id')->unsigned()->index();
            $table->string('content');
            $table->timestamps();

            // 外部キー制約
            $table->foreign('user_id')->references('id')->on('users');
        });
    }

    public function down()
    {
        Schema::dropIfExists('categorys');
    }

カラム追加ではマイグレーションのデッドロックになりやすい

 public function up()
    {
        Schema::table('categorys', function (Blueprint $table) {
            $table->string('bunrui_cd')->unsigned()->index();
            // 外部キー制約
            $table->foreign('bunrui_cd')->references('id')->on('bunruis');
        });
    }

    public function down()
    {
        Schema::table('categorys', function (Blueprint $table) {
            $table->dropColumn('bunrui_cd');
        });
    }

この場合、既存データが存在している場合、bunrui_cdは作成済みで外部キー作成でエラーとなります。マイグレーションはNなので戻るも先へも行けなくなります

対策

(1)カラムと外部キー作成のマイグレーションを分離する

(2)down には外部キー削除をカラム追加の後に行う

  public function down()
    {
        Schema::table('categorys', function (Blueprint $table) {
            $table->dropColumn('bunrui_cd');
            // $table->dropForeign('[テーブル名]_[フォーリンキーを取り除くカラム名]_foreign');
            $table->dropForeign('categorys_bunrui_cd_foreign');
        });
    }

Bootstrapでモーダルダイアログ表示(規約既読用チェックボックス)

はじめに

よく、規約を読まないとボタンが押せないようにするサイトがよくあります。その実装方法をbootstrapモーダルダイアログ表示とチェックボックスによりボタン活性化の方法を示します

サンプルコード(Laravel 含む)

@extends('layouts.app1')

@section('title')
 ご利用申し込み
@endsection

@section('content')

    <h1> ご利用申し込み</h1>

    <div class="row">
        <div class="col-xs-12 col-sm-8 col-sm-offset-2 col-md-8 col-md-offset-2 col-lg-offset-3 col-lg-6  ">
                {!! Form::open(['route'=>'memberCreate']) !!}
                    <BR />
                    <div class="form-group @if(!empty($errors->first('name'))) has-error @endif">
                        {!! Form::label('name','おなまえ(ひらがな入力)') !!}
                        <input type="text" name="name" value="{{old('name')}}" class="form-control">
                        <span class="help-block">{{$errors->first('name')}}</span>

                    </div>

                    <div class="form-group @if(!empty($errors->first('email'))) has-error @endif">
                        {!! Form::label('email','Emailアドレス') !!}
                        <input type="text" name="email" value="{{old('email')}}" class="form-control">
                        <span class="help-block">{{$errors->first('email')}}</span>

                    </div>

                    <div class="form-group @if(!empty($errors->first('email_confirmation'))) has-error @endif">
                        {!! Form::label('email_confirmation','Emailアドレス(確認用)') !!}
                        <input type="text" name="email_confirmation" value="{{old('email_confirmation')}}" class="form-control">
                        <span class="help-block">{{$errors->first('email_confirmation')}}</span>

                    </div>


                    <div class="form-group" style='display:none;'>
                        {!! Form::label('unsubscribe_day','退会年月') !!}
                        {!! Form::month('unsubscribe_day',old('unsubscribe_day'),['class'=>'form-control','value'=>'2999-12']) !!}
                    </div>

                    <div class="form-group">
                        <!-- 切り替えボタンの設定 -->
                        <button type="button" class="btn btn-default" data-toggle="modal" data-target="#Modal">
                            クレジットカードご利用規約を読む
                        </button>
                        <BR>
                        <input type="checkbox" name="agree_privacy" id="agree" value="" required="required" />
                        <label for="agree"> クレジットカードご利用規約を確認し、同意しました。</label>
                    </div>
                    <div class="form-group">
                        <button name="confirm" type="submit" id="submit" value="submit" class="disabled-btn btn btn-primary  btn-block" readonly="readonly">クレジットカード情報登録へ</button>
                    </div>
                {!! Form::close() !!}


  <!-- モーダルの設定 -->

  <div class="modal fade" id="Modal" tabindex="-1" role="dialog" aria-labelledby="Modal" aria-hidden="true">
    <!--以下modal-dialogのCSSの部分で modal-lgやmodal-smを追加するとモーダルのサイズを変更することができる-->
    <div class="modal-dialog modal-lg" role="document">
      <div class="modal-content">
        <div class="modal-header">
          <h3 class="modal-title" id="Modal">クレジットご利用規約について</h3>
          <button type="button" class="close" data-dismiss="modal" aria-label="閉じる">
            <span aria-hidden="true">&times;</span>
          </button>
        </div>
        <div class="modal-body">
            <p>・クレジットカードの決済は、外部サイトより行います。</p>
            <p>・ご利用開始月は無料で利用頂くことができ、翌月XX日より毎月の利用代金(税別999円)をご請求させていただきます。</p>
            <p>・クレジットカードをご登録頂きますとアクチベーションが行われ、ご利用が可能となります。</p>
            <p>・ご利用を終了される場合はホームページより退会申し込みのお手続きをお願いいたします。<BR>
             アプリの削除だけでは月々の課金を停止することができませんので、<br>
                予めご注意下さいますようお願い申し上げます。</p>
            <p>・当サービスは月額決済のため、退会手続き時点でのご利用代金を日割りによる払い戻しはいたしません。<br>
                退会手続き後も月末までは継続してご利用頂けます。</p>
                <BR><BR>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-secondary" data-dismiss="modal">閉じる</button>
          <!--button type="button" class="btn btn-primary">確認いたしました</button -->
        </div>
      </div>
    </div>
  </div>
</div>
</div>

<script>
$(function() {
    $('#submit').prop('disabled', true);

    $('#agree').on('click', function() {
        if ($(this).prop('checked') == false) {
            $('#submit').prop('disabled', true);
        } else {
            $('#submit').prop('disabled', false);
        }
    });
});
</script>
<style>
     /*モーダルの背景の色※モーダル自体の背景ではない*/
     .modal-backdrop {
            background-color: gray;
     }
              /*モーダル全体の背景設定*/
              .modal-content {
            background: yellow;
        }

        /*モーダルのbody要素の背景設定*/
        .modal-body {
            background: white;
        }

</style>
@endsection

読み終えてチェックボックスにチェックを入れますと

ボタンが活性化するJavaScript です。ご活用くださいね

Laravel6.0でのvalidateのメッセージを日本語化する方法

laravelを始められた初学者は、バリデーションチェックを行った際のメッセージが英語となっていることにためらってしまわれますよね。

日本で業務開発するするうえでは、日本語メッセージが必要かと思います

今回はメッセージを日本語にするための手順を示していきます

GitHubより日本語メッセージファイルを取得配置

https://gist.github.com/syokunin/b37725686b5baf09255b

上記より日本語バリデーションメッセージファイルを取得しましょう

resources/lang/ja/validation.php へ格納します

※5.1ベースなのでメッセージに差がありましたら訳した文書を追加してください

言語指定を日本語にします

config/app.php を en → ja

項目名も日本語化する

項目名もメッセージファイルに追記

resources/lang/ja/validation.php の最後に追加です

動作確認(変更前)

動作確認(日本語対応後)

以上となります

手助けになれば幸いです

Laravel バリデーションの指定方法

| 存在チェック

用語 使用例 説明
required required 入力必須
present present フィールドが存在しているかどうか(存在していれば空でも許す)
nullable nullable nullableな内容を許容する
filled filled フィールドが存在する場合は空でないかどうか(存在していなければ許す)
in in:foo,bar 指定されたリストの中の値に含まれているかどうか(例だとfooかbarが値ならOK)
not_in not_in:foo,bar inの含まれない版
in_array in_array:別のフィールド フィールドの中身が別のフィールドの値のどれかであるかどうか

| 型チェック関連

論理値

用語 使用例 説明
boolean boolean 論理値かどうか(文字列の1や0も含む)
accepted accepted yes,on, 1, trueのどれかであるかどうか

文字列判定

用語 使用例 説明
string string 文字列であるかどうか
alpha alpha 中身が全部英字かどうか*1
alpha_dash alpha_dash 英字または-または_であるかどうか*1
alpha_num alpha_num 英数字であるかどうか*1
email email メールアドレスの形式であるかどうか*2
url url URLの形式であるかどうか(filter_var)
active_url active_url URLが有効かどうか(checkdnsrr)
ip ip ipアドレスの形式かどうか
json json json文字列であるかどうか
timezone timezone タイムゾーンの文字列であるかどうか(timezone_identifiers_list)
regex regex:正規表現 正規表現にマッチするかどうか。正規表現にパイプが含まれるときはパイプ不可
uuid uuid フィールドがUUIDの形式にマッチしているかどうか

 

日付判定

用語 使用例 説明
date date 日付かどうか(strtotime)
date_format date_format:”Y-m-d” 日付フォーマットが一致しているかどうか。dateと一緒には使えない
after after:tomorrow
after:start_date
対象の日付以降かどうか(strtotime)。他のフィールドとも比較可能
before before:today ↑の日付以前ばーじょん

afterとかbeforeは期間指定とかするときに役立ちそう

数値判定

用語 使用例 説明
integer integer 整数かどうか
numeric numeric 数値かどうか(is_numeric)
digits digits:2 数値であり、値の桁数であるかどうか(例では2桁)
digits_between digits_between:1,5 数値であり、桁数が最小値から最大値の間かどうか(例だと1~5桁)

配列判定

用語 使用例 説明
array array 配列かどうか
distinct distinct 対象が配列のときに重複がないかどうか

| 大きさ判定

用語 使用例 説明
size size:20 指定された値であるかどうか。文字列の場合は文字長で数値なら整数値、ファイルならキロバイトのサイズ。
min min:1 指定された値以上かどうか。文字にも数値にもファイルにも使える
max max:5 指定された値以下かどうか。文字にも数値にもファイルにも使える
between between:1,5 最小値から最大値の間のサイズかどうか。文字にも数値にもファイルにも使える

| 比較判定

比較判定系のバリデーションはすでにマージされていて、minやmaxなどと異なる点は、比較判定系は同じ型であることが要求され、フィールド名を指定することも可能である点です。

用語 使用例 説明
gt gt:数値またはフィールド名 対象の数値より大きいかどうか(>)
gte gte:数値またはフィールド名 対象の数値以上かどうか(>=)
lt lt:数値またはフィールド名 対象の数値より小さいかどうか(<)
lte lte:数値またはフィールド名 対象の数値以下かどうか(<=)

| ファイル判定

用語 使用例 説明
file file ファイルであるかどうか
image image ファイルが画像かどうか(jpg,png,bmp,gif,svg)
dimensions dimensions:パラメータ バリデーションする画像がパラメータに指定されたサイズに一致するか(min_width,max_width,min_height,max_height,width,height,raito)
mimes mimes:jpg,png ファイルが指定された拡張子かどうか

dimensionsは5.4からルールの指定をコードでやることも可能。
(Rule::dimensions()->maxWidth(1000)->maxHeight(500)->ratio(3 / 2))

| 同値チェック

用語 使用例 説明
confirmed confirmed フィールド名_confirmationフィールドと同値であるかどうか
same same:フィールド名 指定したフィールドと同じ値であるかどうか
different different:フィールド名 指定フィールドと値が異なるかどうか

| その他

exists

例1: exists:states
上記の場合は、statesテーブルのフィールド名カラムにフィールドの値が存在することを確認します。なので、"state" => "exists:states"という指定の場合はstatesテーブルのstateカラムということになります。

例2: exists:states,abbreviation
上記の場合は、statesテーブルのabbreviationカラムにフィールドの値が存在することを確認します。

例3: exists:staff,email,account_id,1
staffテーブルのaccount_idが1であるレコードのemailカラムにフィールドの値が存在することを確認します。(つまりwhereです)
1の部分は!を使って条件否定も出来たり、NULLやNOT_NULLの指定も可能です。

例4: Ruleクラス(Existsクラス)を利用した書き方

例3のようになってくると、コード化しておいたほうがわかりやすいのでこちらを使うほうが良いでしょう。

 
use Illuminate\Validation\Rule;

Validator::make($data, [
    'email' => [
        'required',
        Rule::exists('staff')->where(function ($query) {
            $query->where('account_id', 1);
        }),
    ],
]);

unique

uniqueは一意であることを確認します。existsとほとんど変わりません。

よくある例は、"email" => "unique:users,email_address"みたいな感じですね。
なお、バリデータは基本的にデフォルトのデータベース接続を行うのでもしも指定したい場合はunique:connection名.usersのようにするみたいです。

existsと違う点は第3パラメータ以降です。existsでは第3パラメータ以降はwhereだったのですが、uniqueの場合は違います。
uniqueの場合、第3パラメータには除外したいIDを指定します。これがある理由は、自身の情報を更新している際にuniqueチェックが入ってしまうとエラーになってしまうからです。
(email以外のフィールドを更新しているのに、emailもformに渡された結果、validationの際にuniqueチェックで失敗する)

また、第4引数には第3引数を適用するカラム名を指定できます。デフォルトではidが指定されています。

この第3、4パラメータを除いて、whereを書くには以下のようにする必要があります。

 
'email' => 'unique:users,email,NULL,id,account_id,1'

訳:usersテーブルでidカラムがnullの物を除き、account_idが1の物でemailカラムがフィールドの値に存在しないことを確認します。(select count(id) from users where id is not null and account_id = 1 and email = ?みたいな感じだと思われ)

また、5.3以降ではRuleクラス(Uniqueクラス)を利用した書き方も出来ます。

 
use Illuminate\Validation\Rule;

Validator::make($data, [
    'email' => [
        'required',
        Rule::unique('users')->ignore($user->id),
    ],
]);

required_ifとrequired_unless

例1:required_if:state,0
例2:required_if:flag,1,2

flagフィールドに1または2を持っている場合に、このフィールドが入力されているかを確認します。(例2)unlessの場合は持っていない場合に確認します。

required_withとrequired_with_all

例: required_with:foo,bar

fooまたはbarフィールドが存在している場合だけ、このフィールドが入力されているかを確認します。with_allは指定されているフィールド全てが存在している場合です。

required_withoutとrequired_without_all

上記のrequired_with,with_allの逆バージョンです。存在しない時に入力チェックが走ります。

今後、気づき都度次第メンテナンスしていこうと思ってます

Laravel バリデーション かな対応

laravelの標準バリデーションで かな などチェックがないので自分で考えてみました。

$this->validate で直接記述する単純なものです

参考にお使いください

$this->validate($request, [
        'name' => 'required',
        function ($attribute, $value, $fail) {
           if (preg_match('/[^ぁ-んー]/u', $value) !== 0) {
                return $fail('かなはひらがなで入力してください');
            }
        },
        'email' => 'required|email|confirmed',
]);