20200121のPHPに関する記事は12件です。

【緊急事態】PHPのセッション変数が引き継げない!!

開発環境で動いていたプログラムが、
本番環境にいったら動かない!!
ということはよくある。

多いのは、どこまでをエラーとして出力するかの定義の差の場合が多い。

昔からの資産があると、どうしてもワーニングが出てしまう事がある。本当はワーニングを出ないようにすべきなのだが。。。

そのような場合、多くは
.htaccessに
php_value error_reporting 30711
と書けば問題は解決してくれる。

しかし、今回は違った、ログインの情報をセッション変数に入れているのだが、リダイレクトするとその情報が引き継げないという現象が起きた。

ネットで調べると、多くはsession_start();の前に、
何かを出力してしまった事が原因という単純なもの。

ようやっと、リダイレクトでうまくいかないとの報告は見つけたが、その解決策は無し。

本番環境の構築の期限は迫っている。

しょうがないので、セキュリティー的にはNGなんだろうが、画面遷移をするためのformを用意して、それを使う事でとりあえず納品とした。

同じプログラムをデモとして別のサーバにもアップした。サーバはmix-host。
ログインなどは問題なく出来ているが、
error.log
なるものが出力されていることに気がついた。

その内容は、

session_start(): Cannot start session when headers already sent in

session_start()が失敗する?

コードは

<?php
session_start();
:

とその前には何もない。

しかし、エラーメッセージから調べると、
ファイルにBOMが付いているとsession_start();が失敗するとのページを見つけた。

セッション変数を引き継げないページのsession idを調べると何も設定されていなかったのを思い出す。

恐る恐るBOMを確認する、付いていた!!

BOMを外してみた。

formが無くても動く!!

シンプルにsession_start();が失敗していたのか。

mix-host を使わないとわからなかった。

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

【Laravel - AWS】composer install が mbstring のエラーで失敗するとき

結論だけ知りたい

$ sudo yum install php{$ver}-mbstring.x86_64

$ver はインストールしたPHPのバージョンに合わせる。

PHPバージョン7.2系をインストールしている場合は

$ sudo yum install php72-mbstring.x86_64

とすればOK。心配な人はPHPのバージョンを確認しましょう。

前提

Amazon Linuxの公式ガイドに沿ってLAMP環境を構築。

基本は記事に忠実に。ただ途中、phpのバージョンを70→72に指定した。

バージョン情報
Laravel : 6.9
PHP : 7.2.24
AWS : EC2 - AmazonLinux

▼上記の記事に書かれているコマンド▼

[ec2-user ~]$ sudo yum install -y httpd24 php70 mysql56-server php70-mysqlnd

▼実際に打ち込んだコマンド▼

[ec2-user ~]$ sudo yum install -y httpd24 php72 mysql56-server php72-mysqlnd

起きたこと

ローカルのLaravelを本番でgit経由でpullし、 composer install しようとしたタイミングでエラー。

エラー内容

[ec2-user@ip-XXX src]$ composer install
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Installation request for erusev/parsedown 1.7.3 -> satisfiable by erusev/parsedown[1.7.3].
    - erusev/parsedown 1.7.3 requires ext-mbstring * -> the requested PHP extension mbstring is missing from your system.
  Problem 2
    - Installation request for laravel/framework v6.9.0 -> satisfiable by laravel/framework[v6.9.0].
    - laravel/framework v6.9.0 requires ext-mbstring * -> the requested PHP extension mbstring is missing from your system.
  Problem 3
    - Installation request for facade/ignition 1.13.0 -> satisfiable by facade/ignition[1.13.0].
    - facade/ignition 1.13.0 requires ext-mbstring * -> the requested PHP extension mbstring is missing from your system.
  Problem 4
    - Installation request for phpunit/phpunit 8.5.1 -> satisfiable by phpunit/phpunit[8.5.1].
    - phpunit/phpunit 8.5.1 requires ext-mbstring * -> the requested PHP extension mbstring is missing from your system.
  Problem 5
    - Installation request for scrivo/highlight.php v9.17.1.0 -> satisfiable by scrivo/highlight.php[v9.17.1.0].
    - scrivo/highlight.php v9.17.1.0 requires ext-mbstring * -> the requested PHP extension mbstring is missing from your system.
  Problem 6
    - laravel/framework v6.9.0 requires ext-mbstring * -> the requested PHP extension mbstring is missing from your system.
    - facade/flare-client-php 1.3.1 requires illuminate/pipeline ~5.5|~5.6|~5.7|~5.8|^6.0 -> satisfiable by laravel/framework[v6.9.0].
    - Installation request for facade/flare-client-php 1.3.1 -> satisfiable by facade/flare-client-php[1.3.1].

何やら長々とエラーが出ているが、全部のエラーで php-extensionの mbstring が無いということなのでそれをインストールすれば良さそう。

調べてみると yum install --enablerepo=remi-php72 php-mbstring でインストールできるとのこと。

しかしコマンドを打ち込んだらまた怒られる。

[ec2-user@ip-XXX src]$ sudo yum install --enablerepo=remi-php72 php-mbstring
読み込んだプラグイン:priorities, update-motd, upgrade-helper


Error getting repository data for remi-php72, repository not found

リポジトリが見つからないということなのでリポジトリのコマンドを外す。

[ec2-user@ip-XXX src]$ sudo yum install php-mbstring
読み込んだプラグイン:priorities, update-motd, upgrade-helper
依存性の解決をしています
--> トランザクションの確認を実行しています。
---> パッケージ php-mbstring.x86_64 0:5.3.29-1.8.amzn1 を インストール
--> 依存性の処理をしています: php-common(x86-64) = 5.3.29-1.8.amzn1 のパッケージ: php-mbstring-5.3.29-1.8.amzn1.x86_64
--> トランザクションの確認を実行しています。
---> パッケージ php-common.x86_64 0:5.3.29-1.8.amzn1 を インストール
--> 衝突を処理しています: php72-common-7.2.24-1.18.amzn1.x86_64 は php-common < 5.5.22-1.98 と衝突しています
--> 依存性解決を終了しました。
エラー: php72-common conflicts with php-common-5.3.29-1.8.amzn1.x86_64
 問題を回避するために --skip-broken を用いることができます。
 これらを試行できます: rpm -Va --nofiles --nodigest

バージョンがコンフリクトしたらしい。どうやらインストールしているパッケージ自体がおかしい気がする。

よくよく調べると、AmazonLinuxはデフォルトで自前のリポジトリを最優先で探すことがわかった。

これを回避する方法は

  1. 対応するパッケージをAmazonLinux公式のリポジトリから落とす。
  2. リポジトリ優先度の設定をする。

の2つと考えられる。

今回は mbstring がインストールできれば良いので1の方法で行くことにした。

2の方法についてはこちらの記事がわかりやすい。
Amazon LinuxでYUMを使う時に気をつけるポイント | Developers.IO

対応パッケージを探す

Amazon公式のリポジトリは
php72-cli.x86_64
のように、バージョンとパッケージ名を同時に指定する方式になっている。

今回は72に対応するパッケージが欲しいのでgrepを使って探す

[ec2-user@ip-XXX src]$ yum list | grep php72
php72.x86_64                          7.2.24-1.18.amzn1             @amzn-updates
php72-cli.x86_64                      7.2.24-1.18.amzn1             @amzn-updates
php72-common.x86_64                   7.2.24-1.18.amzn1             @amzn-updates
php72-json.x86_64                     7.2.24-1.18.amzn1             @amzn-updates
php72-mbstring.x86_64                 7.2.24-1.18.amzn1             @amzn-updates
php72-mysqlnd.x86_64                  7.2.24-1.18.amzn1             @amzn-updates

...

mbstringも発見したので、これをインストールしてみる。

[ec2-user@ip-XXX src]$ sudo yum install php72-mbstring.x86_64
読み込んだプラグイン:priorities, update-motd, upgrade-helper
依存性の解決をしています
--> トランザクションの確認を実行しています。
---> パッケージ php72-mbstring.x86_64 0:7.2.24-1.18.amzn1 を インストール
--> 依存性解決を終了しました。

依存性を解決しました

=================================================================================================================
 Package                     アーキテクチャー    バージョン                      リポジトリー               容量
=================================================================================================================
インストール中:
 php72-mbstring              x86_64              7.2.24-1.18.amzn1               amzn-updates              1.4 M

トランザクションの要約
=================================================================================================================
インストール  1 パッケージ

総ダウンロード容量: 1.4 M
インストール容量: 3.2 M
Is this ok [y/d/N]: y
Downloading packages:
php72-mbstring-7.2.24-1.18.amzn1.x86_64.rpm                                               | 1.4 MB  00:00:00     
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  インストール中          : php72-mbstring-7.2.24-1.18.amzn1.x86_64                                          1/1 
  検証中                  : php72-mbstring-7.2.24-1.18.amzn1.x86_64                                          1/1 

インストール:
  php72-mbstring.x86_64 0:7.2.24-1.18.amzn1                                                                      

完了しました!

無事インストールできたので、改めて composer install してみる

[ec2-user@ip-XXX src]$ composer install
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Package operations: 85 installs, 0 updates, 0 removals

...

Package manifest generated successfully.

無事通った。

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

Laravelではメール送信やSlack通知のテストが簡単だって知ってましたか?

メールやSlack通知のテストしてますか?
通知のテストはし難いのですが、Laravelではモックが充実しているので簡単にテストすることができます。

参考: https://readouble.com/laravel/6.x/ja/mocking.html

環境

  • PHP v7.2
  • Laravel v6.x
  • PHPUnit v7.5

テストする方法

以下のようにpostのテストを実行する前に Mail Facade で fake を差し込むようにしておく。
postテスト実行した後に、assertSent() でMailableクラスの処理が走っているかテストできます。

use Illuminate\Support\Facades\Mail;

class IndexControllerTest extends TestCase
{
    public function testIndex()
    {
        Mail::fake();

        $this->post('/path/to/something/post', ['text' => 'ダミーテキスト'])->assertRedirect();

        // MessageCreatedクラスは、Mailableをextendsしたものです。実行されているべきMailableをフルパスで指定します。
        Mail::assertSent(MessageCreated::class);
    }
}

おまけ

notificationもテストできます。

Slack通知など。
ドキュメントの Notification Fake のところを参照してください。
「テストをかけるよ」ということを知識として知っていないとなかなかかけないのでここで紹介だけしておきます。

ハマりどころ

最初、以下のように書いて動かずにハマったので共有しておきます。

    public function testIndex()
    {

        $this->post('/path/to/something/post', ['text' => 'ダミーテキスト'])->assertRedirect();

        // postのテストが終わった後にfake差し込み
        Mail::fake();
        Mail::assertSent(MessageCreated::class);
    }

fakeを差し込むタイミングが終わった後なので意味がありません。

面倒なので毎回 fake を書きたく無い場合

setUp()のなかで処理を追加しておきましょう。
毎回クラスに書いてもいいのですが、これを差し込んだ共通親クラスを作っておくともっと楽チンです。

    protected function setUp(): void
    {
        parent::setUp();

        Mail::fake();
    }

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

Wordpressの翻訳が読み込まれないと思ったときに確認すること

以下を確認して、設定が正しいかをチェックするとよい。

1.Plugin情報が書いてあるPHP File

plugin.php
<?php
/*
  Plugin Name: HogeHoge
  Description: HogeHoge
  Version: 1
  License: GPL2
  Text Domain: hoge-plugin    ← ここ
  Domain Path: /languages/
*/
?>

2. ファイルが適切な位置に保存されているか。

ファイルは以下のルールで保存されていることが期待されている。
($PLUGIN_ROOT_DIR はプラグインがインストールされているディレクトリ)

$PLUGIN_ROOT_DIR/$DOMAIN_PATH/$TEXT_DOMAIN-ja.mo

上記の設定に従うと、moファイルが以下の場所に格納されていると期待されている。

$PLUGIN_ROOT_DIR/languages/hoge-plugin-ja.mo

3. load_text_domain関数に渡されている引数

load_text_domain関数は第1引数が設定ファイルに書かれた Text Domain、 第2引数が false、第3引数が moファイルが格納されているWP_PLUGIN_DIRの相対パス を入れる必要がある。

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

PHPの予約語

PHPの予約語

PHP で定義済みの ID の一覧を示します。
ここに示す ID はいずれも、 別途明記されていない限りは
スクリプトの中で ID として使用することはできません。
これらの一覧には キーワード、定義済みの変数、定数、クラス名が含まれています。
これらの一覧は、 全てを網羅しているわけではありません。

PHP公式リファレンス

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

ご教授願いたいです。

プログラミングを学び始め、PHPの本を購入し、勉強しているのですが
下記のソースを実行した際
スタッフ名のみ表示させたいのですが、暗号化されたパスまで表示されてしまいます。

また、print したい部分も表示されず、真っ白になってしまいます。
しかし、データベースには情報は登録されています。

どこが悪くてエラーになってるか分からないのでご教授いただけませんでしょうか

<?php

try
{

$staff_name = $POST['name'];
$staff_pass = $
POST['pass'];

$staff_name = htmlspecialchars($staff_name,ENT_QUOTES,'UTF-8');
$staff_pass = htmlspecialchars($staff_pass,ENT_QUOTES,'UTF-8');

$dsn ='mysql:dbname=shop;host=localhost;charaset=utf8';
$user ='root';
$password ='';
$dbh = new PDO($dsn,$user,$password);
$dbh ->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);

$sql = 'INSERT INTO mst_staff(name,password) VALUES (?,?)';
$stmt = $dbh->prepare($sql);
$data[] = $staff_name;
$data[] = $staff_pass;
$stmt ->execute($data);

$dbh = null;

 print $staff_name;
 print 'さんを追加しました。<br />';

}
catch (Exception $e)
{
print 'ただいま障害により大変ご迷惑をお掛けしております。';
exit();
}

?>

戻る

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

【PHP】三項演算子はどこで使えばいいのか?という話

三項演算子とは、if文の親戚的な何かであると耳にしたことのある人は多いかと思います。
プログラミング言語には大抵三項演算子が使える仕様になっています。
この三項演算子がしてくれる事と言えば、

1、条件式を作る
2、条件式に合致すればAの処理をする
3、条件式に合致しないのならBの処理をする

と言った事をしてくれるのです。

しかしここで疑問が幾つか湧き出ました。

「これって、IF文と何が違うんだ?」
「具体的にどこで使うんだ?」

ここではそんな疑問に答えていこうと思います。

ところで何故タイトルに【PHP】だなんて入れたんだ?と思うかも知れませんが、これは中の解説で使う言語がPHPだからで、ここでの解説は別に他の言語でも通じる話かと思います。

三項演算子の使いどころは「真」「偽」で処理する時

まず簡単に言えば、if文より短く書ける場合に使う事があります。

1つの例として、if文の場合こんな感じに記述をしたとしましょう。

test.php
$hoge = 1;

if($hoge === 1){
  $hoge = "1です";
}else{
  $hoge = "1ではないです";
};

echo $hoge;

これはつまり、

  • $hogeに「1」を代入
  • $hogeの中身が1の時には「1でした」と代入
  • $hogeの中身が1以外の時は「1ではないです」と代入
  • $hogeの中身を出力する

というソースコードです。

IF文の場合、プログラムを見やすくするために、インデント(改行)はなるべく利用したいですからどうしても縦に長いコードになります。

そこで三項演算子の出番という訳です。
上記と同じコードをここまで小さく表現できます。

test
$hoge = 1;

$hoge = $hoge === 1 ? "これは1です":"これは1ではありません";
echo $hoge;

これが上記のコードと同じ結果を産むと言えば、効率的な書き方である事が解るかと思います。

ちなみに三項演算子とはどのような書き方なのか解説すると、

説明
条件式 ? 真の場合の出力 : 偽の場合の出力;

条件式に「何が”真”か?」を定義すれば、後は"?"以降の構文が出力を振り分けてくれます。

まとめ

つまり、三項演算子は「真」「偽」で出力を変えたい時に、if文よりより労力をかけずにソースコードを完成させられる仕組みなのです。

三項演算子の使い方を具体的に考え直してみると、

・正しいか間違いかの処理
・AかBのいずれかしかない処理
・ON/OFFの切り替えスイッチ的な処理
・合格か不合格か判定する処理

と言ったものに使えそうです。

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

【PHP】ファイル入出力、dirnameとbasename結合時の注意点|'/'を忘れずに!

web系エンジニアを目指し、MENTAを利用し、PHPを学習している初学者です。
日々学習していることの忘備録、モチベ維持、ちゃんとやってることの証明!で、投稿していきます。
(今回の内容もなんてことないのですが、一瞬「??」となったので、メモ)

対象者

PHPを学びはじめた、初学者

内容

ファイル入出力設定時便利な、dirnameとbasename結合時の注意点

動作環境

PHP 7.1.32

基本のおさらい

ファイル入出力とは

プログラムに書いた通り、
・ファイルを読み込んだり
・ファイルに書き込んだり
・ディレクトリを作成したり
することが出来ます。
GUIでしかパソコンを触ってこなかった私からすると、ちょっと感動!

ファイル入出力のイメージ
//対象のファイル
$filepath = './a/b/c/hoge.csv';

//ファイルを読み込む
1、開いて
$hondle_read = fopen($filepath, 'r');

2、読み込んで
while($read[] = fgets($handle_read))

3、閉じる
fclose($handle);

//ファイルへ書き込む
1、開いて
$handle_write = fopen($filepath, 'w');

2、書き込んで
$write = 'ファイルに書き込む内容';
fwrite($handle_write, $write);

3、閉じる
fclose($handle_write);

このコードは問題有り

一定の条件
$filepathのディレクトリ+ファイルが実在していれば、読み込み
$filepathのディレクトリがあれば、書き込み
が実現しますが、本来は
・ディレクトリがあるか検証
・ファイルがあるか検証
・ファイル内の改行を意識
などが必要です。
公式リファレンスがわかりやすいので、基礎を学びたい方はご参照ください。
PHPマニュアル fgets

これが本題!

メンターさんからの課題を解く中、
$filepathからディレクトリ部分・ファイル部分を抜き出す関数
dirname,basename
を教えてもらい、早速使ってみるも思い通りに動かない!

今回書きたいのは、
dirnameとbasename結合時の注意点です。

dirname,basenameとは
//対象のファイル
$filepath = './a/b/c/hoge.csv';

//dirname
$directory = dirname($filepath);
echo $directory; // ./a/b/c

//basename
$filename = basename($filepath);
echo $filename;  // hoge.csv

このように、きれいに$filepathからディレクトリ部分・ファイル部分を抜き出してくれるんです!素晴らしい。

でもよくみて下さい。
ディレクトリ「c」と、ファイル「hoge.csv」の間にあった「/」がなくなってる!
なので、これらを結合する時は十分に気を付けて下さいね。

「・・・だから?」
「どう気を付ければ?」
「どんな場面で、その必要が出てくるの?」
そんな初学者の方向けに、実例を出して終了します。

実例

「連番のファイル名にして出力せよ!」というような課題で、意気揚々とdirname,basenameを使用するも、変なファイル名になってしまう・・

失敗例と解決策
上記の続き
//作成したいファイル
'./a/b/c/hoge_1.csv'
'./a/b/c/hoge_2.csv'
'./a/b/c/hoge_3.csv'

失敗例
//ファイル名にfor文で番号を付加して、ディレクトリと結合すれば、新しいファイルパスの完成だ!
for($i = 1; $i <=3; $i++) {
    $filepath[$i] = $directory . $filename . '_' . $i;
}

//$filepath[1]〜[3]を使ってファイル書き出し。出来上がったのは・・
'./a/b/choge_1.csv'
'./a/b/choge_2.csv'
'./a/b/choge_3.csv'

解決策
for($i = 1; $i <=3; $i++) {
    $filepath[$i] = $directory . '/' .$filename . '_' .$i;
}

//$filepath[1]〜[3]を使ってファイル書き出し
'./a/b/c/hoge_1.csv'
'./a/b/c/hoge_2.csv'
'./a/b/c/hoge_3.csv'

なんてことないですね!

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

Laravelで大規模プロジェクトと戦うにはRepository層を導入するといいかも

Laravelをなんとなく書いていると起こる問題点

  • コントローラ膨らみすぎ問題
  • Model膨らみすぎ問題
  • MdoelにORMマッパーにベタベタに依存したビジネスロジックを書いてしまってテスト書くのがしんどくなる問題

設計方針

  1. 重要度が高いビジネスロジックはDBやLaravelの機能に依存させない
    LaravelのModelにビジネスロジックを書いてしまうとEloquent依存のコードを簡単にかけてしまいます。
    とりあえず動かすにはこれが一番早いので選択肢としてはありかと思いますが、後に機能が複雑になってくるとテスト結果がDBの状態になったりテストがしにくくなるのでやめましょう
    とはいえEloquentは便利なのでRepository内で使いましょう

  2. できるところはLaravelに依存する
    ログイン、ページネーション、バリデーションなどはLaravelに依存しましょう。

  3. できる限りテストを簡単に
    テストを簡単にかけるような設計でないとテスト書くのが苦痛になり、テストが雑になりがちです。

解決策

DDDや、クリーンアーキテクチャはそのまま導入しようとしましたが、現状に対してあまりに壮大過ぎる&チームでやるには学習コストが高すぎるので以下を導入することにしました。

Modelからビジネスロジックを分離させる

Entitiesディレクトリを新規に作成し、ここに重要度が高いビジネスロジックをModelに依存させない形で作成します。
LaravelのFacadeも使ってはいけません。CakePHPやWordPressにそのままコピペできるようにしましょう。

<?php


namespace App\Entities;


class Video
{
    protected int $id;
    protected string $title;
    protected string $description;
    protected string $publish_at;
    protected User $author;

    /**
     * @return int
     */
    public function getId(): int
    {
        return $this->id;
    }

    /**
     * @return string
     */
    public function getTitle(): string
    {
        return $this->title;
    }

    /**
     * @return string
     */
    public function getDescription(): string
    {
        return $this->description;
    }

    /**
     * @return User
     */
    public function getAuthor(): User
    {
        return $this->author;
    }

    /**
     * @return User|string
     */
    public function getPublishAt()
    {
        return $this->publish_at;
    }

    /**
     * Video constructor.
     * @param int $id
     * @param string $title
     * @param string $description
     * @param string $publish_at
     * @param User $author
     */
    public function __construct(int $id, string $title, string $description, string $publish_at, User $author)
    {
        $this->id = $id;
        $this->title = $title;
        $this->description = $description;
        $this->publish_at = $publish_at;
        $this->author = $author;
    }

    public function check_publish(){
        // いろいろなロジックを書いていく
    }
}

Repository層の導入

Repositoriesディレクトリを作成し、ここでEloquentを使いながら上のEntityを作成します。
まずはapp/Repositoriesにインターフェイスを作成します。インターフェイスを作成することでデータベースへの依存を防げます。

<?php


namespace App\Repositories;


use App\Entities\Video;

interface VideoRepository
{
    public function getById(int $id): ?Video;
}

app/Repositories/implに実際にEloquentを使った組み込みを書いていきます。

<?php


namespace App\Repositories\impl;


use App\Entities\Video;
use App\Repositories\VideoRepository;

class VideoDBRepository implements VideoRepository
{
    function getById(int $id): ?Video
    {
        $video = \App\Model\Video::find($id);
        if(empty($video)){
            return null;
        }
        return new Video($video->id, $video->title, $video->discription, $video->author}
}

サービスプロバイダーを追加し、VideoRepositoryとVideoDBRepositoryをバインドします。
これでVideoRepository参照するとVideoDBRepositoryが読み込まれます。
VideoRepositoryに依存することにより入れ替えで簡単にテストができます。

<?php

namespace App\Providers;

use App\Repositories\impl\VideoDBRepository;
use App\Repositories\VideoRepository;
use Illuminate\Support\ServiceProvider;

class RepositoryServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     */
    public function register(): void
    {
    }

    /**
     * Bootstrap services.
     */
    public function boot(): void
    {
        $this->app->bind(VideoRepository::class, VideoDBRepository::class);
    }
}

実際にリポジトリを使用する時はコンストラクタインジェクションを使います。
サービス・プロバイダーでbindしているのでInterfaceからアクセス可能です。

<?php

namespace App\Http\Controllers;

use App\Entities\Video;
use App\Repositories\VideoRepository;


class VideoController extends Controller
{
    protected VideoRepository $videoRepository;

    /**
     * VideoController constructor.
     * @param VideoRepository $videoRepository
     */
    public function __construct(VideoRepository $videoRepository)
    {
        $this->videoRepository = $videoRepository;
    }

    public function video(VideoRequest $request){
        /** @var Video $video */
        $video = $this->videoRepository->getById($request->get('id'));
        return view('video', [
            'video' => $video
        ]);
    }
}

まとめ

ControllerはRepositoryのIntarfaceに依存しているので、ControllerはDBを意識しないでよくなりました。
テスト用のMockRepositoryでも、DBではなくAPIで永続化をするApiRepositoryでもimpl組み込みを追加しbindし直すだけで対応が可能になりました。
そしてEntityではRepositoryもControllerも意識する必要がありません。ロジックのテストにDBの依存が入らないのでテストがやりやすくなります。

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

ReflectionException Class does not exist 原因まとめ

ReflectionException Class does not existが出現するときの原因

違う原因で何度か遭遇したのでまとめます。

  1. useし忘れ -> ちゃんとuseする。
  2. autoloaderが壊れる -> composer dump-aoutoload
  3. sintax error -> 直す

3はPHPのバージョンに寄ったりするようで、ローカルでは問題ないけど、本番環境ではエラーが発生するという事象で少し厄介でした。

参考

https://qiita.com/yoshinyan/items/5116bd30f2d1f2b1d865
https://qiita.com/K-Shuuun/items/c48292cd4186a2c1c8fd

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

2020年 ITカンファレンスまとめ

2020年に開催されるITカンファレンス

1月20日時点のまとめです。
随時、更新します。

言語

PyCon JP

Pythonに関するカンファレンス
日程: 8月28日、29日の予定
場所: 大田区産業プラザPiO
公式サイト

PHPカンファレンス

PHPに関するカンファレンス
日程: 10月11日
場所: 大田区産業プラザPiO
2019公式サイト
2020公式サイト

PHPerKaigi

PHPに関するカンファレンス
日程: 2月9日 16:30〜
2月10日 10:00〜
2月11日 10:00〜
場所: 練馬区立区民・産業プラザ Coconeriホール
2020公式サイト

JSConf JP

JavaScriptに関するカンファレンス
開催不明
去年
日程:11月30、12月1日
場所:アーツ千代田 3331
2019公式サイト

RubyKaigi

Rubyに関するカンファレンス
日程:4月9日、11日
場所:長野県 まつもと市民芸術館
公式サイト

Go Conference

Goに関するカンファレンス 春、秋開催
開催不明
去年
日程:秋 10月28日
場所:みどりコミュニティセンター
2019公式サイト

YAPC

Perlに関するカンファレンス
日程:3月27日、28日
場所:京都
公式サイト

JJUG

Javaに関するカンファレンス
開催不明
去年
日程:春 5月18日、秋 11月23日
場所:ベルサール新宿グランドコンファレンスセンター
春 公式サイト
秋 公式サイト

TSConf JP

TypeScriptに関するカンファレンス
日程:2月22日
場所:NAVITIME JAPAN
公式サイト

try! Swift

Swiftに関するカンファレンス
日程:3月18日,19日
場所:ベルサール渋谷ファースト
公式サイト

FW

DjangoCongress JP

Djangoに関するカンファレンス
日程: 6月20日
場所: 長野市生涯学習センター
公式サイト

Laravel JP Conference

Larabelに関するカンファレンス
日程:3月21日
場所:グランパークカンファレンス
公式サイト

CakeFest

CakePHPに関するカンファレンス
開催日不明
今年は海外の可能性大
公式サイト

VueFes Japan

Vueに関するカンファレンス
開催不明
去年
日程: 10月12日
場所: TOC五反田メッセ
公式サイト

React Conf Japan

Reactに関するカンファレンス
日程:5月21日
場所:株式会社ナビタイムジャパン
公式サイト

ng-japan

Angularに関するカンファレンス
開催不明
去年
日程:7月13日
場所:Google Tokyo Office
公式サイト

NodeTokyo

Node.jsに関するカンファレンス
開催不明
去年
日程: 10月5日
場所: 丸の内 vacans
公式サイト

スマホ

PWA Night

PWAに関するカンファレンス
日程:2月1日
場所:Abema Towers 10F セミナールーム
公式サイト

iOSDC

iOSに関するカンファレンス
開催不明
去年
日程:9月5日、6日、7日
場所:早稲田大学 理工学部西早稲田キャンパス63号館
2019公式サイト

DroidKaigi

Androidに関するカンファレンス
日程:2月20日、21日
場所:五反田TOCビル 13F
公式サイト

Android Bazaar and Conference

開催不明
去年
日程:5月26日
場所:東海大学 高輪キャンパス
2019公式サイト

その他

AWS SUMMIT TOKYO/OSAKA

日程:5月13日、14日、15日
場所:パシフィコ横浜
日程:6月30日
場所:ホテルニューオータニ大阪
公式サイト

Google Cloud Next

開催不明
去年
日程:7月30日、8月1日
場所:東京プリンスホテル
ザ プリンス パークタワー東京
2019公式サイト

Microsoft Ignite The Tour Tokyo

Microsoftに関するカンファレンス
開催不明
去年
日程:12月5日、6日
場所:ザ・プリンス パークタワー東京
公式サイト

PostgreSQL Conference Japan

開催不明
去年
日程: 11月15日
場所: AP品川9階
2019公式サイト

Adobe MAX Japan

Adobeに関するカンファレンス
日程:11月24日
開催:パシフィコ横浜
公式サイト

Unite Tokyo

Unityに関するカンファレンス
開催不明
去年
日程:9月25日、26日
場所:グランドニッコー東京 台場
2019公式サイト

CEDEC

ゲームに関するカンファレンス
日程:9月2日、3日、4日
場所:パシフィコ横浜 ノース
公式サイト

Object-Oriented Conference

Object指向に関するカンファレンス
日程:2月16日
場所:お茶の水女子大学
公式サイト

VimConf

Vimに関するカンファレンス
開催不明
去年
日程:11月3日
場所:アキバホール
2019公式サイト

Digital Thinkers Conference

デザインに関するカンファレンス
日程:1月23日、24日
場所:イイノホール&カンファレンスセンター
公式サイト

MeetUp

Docker Meetup Tokyo

Dockerに関するミートアップ
公式サイト

Kubernetes Meetup Tokyo

Kubernetesに関するミートアップ
公式サイト

Twitter

最近、Twitter始めました。
ぜひ友達募集中です!
https://twitter.com/apasn1

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

【Laravel】条件付きで必須チェックの組み合わせを実現する。

「hoge 且つ fuga()」 が真の時に、hogeの必須チェックを有効にする

    /**
     * 条件付き必須チェックの組み合わせを実現。
     * @param Validator $validator
     */
    public function withValidator(Validator $validator)
    {
        // 「hoge 且つ fuga」の時には必須チェックを有効にする
        $validator->sometimes('hoge', ['nullable', $this->fuga()], function ($o) {
            return $o->hoge == true;
        });
    }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む