20200402のPHPに関する記事は16件です。

本日の学習内容part6

はじめに

こんにちは。閲覧頂きありがとうございます。okayamanです。
今回からPHPフレームワークLarabel入門第2版の学習した内容をアウトプットしていきますのでよろしくお願いします。(もし、間違っている箇所があれば教えて下さい。ものすごく助かります。)ちなみにこの学習内容はLaravel 6、PHP 7で行っております。

~P38まで終了

ルーティングの基本->Route::get()

ルーティングとはあるアドレスにアクセスしたとき、どの処理を呼び出し実行するかを管理するもの。
Route::の後に来る単語や()内の記述によって処理が変わる。ここではRoute::getを取り上げる。

Route::get('hi', function() {
    return '<html><body><h1>Hi</h1><p>test page</p></body></html>';
});

上記のコードは第1引数がアドレス、第2引数が関数になっており
http://localhost:8000/hiにアクセスするとhtmlタグに囲まれた部分が戻り値となる。

ヒアドキュメント

PHPで長い文章を記述するのに使われる。<<<演算子を使って、リスト内に記述されたテキストを変数に代入できる。

<?php

$test = <<<EOF
<html>
<head>
<title>Hey!!</title>
<style>
body {font-size:30px; color:black;}
h1 {font-size:60px; text-align:center; color:blue;}
</style>
</head>
<body>
<h1>こんにちは</h1>
<p>テストテスト</p>
</body>
</html>
EOF;

echo $test;

?>

$testを出力するだけで上記のHTMLが表示される。

上記の2つを組み合わせると・・・

<?php

$test = <<<EOF
<html>
<head>
<title>Hey!!</title>
<style>
body {font-size:30px; color:black;}
h1 {font-size:60px; text-align:center; color:blue;}
</style>
</head>
<body>
<h1>こんにちは</h1>
<p>テストテスト</p>
</body>
</html>
EOF;

Route::get('hey', function() use ($test) {
   return $test;
});

http://localhost:8000/heyにアクセスするとヒアドキュメント部分が戻り値として返る。

さいごに・・・

サンプルコードを見て、頭で理解はしているが、いざ説明しようとすると時間がかかる。これを続けていると人に説明する時に生きてくる気がする。。。気のせいかな??笑

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

【PHP】基礎メモ

最初に

自身で学習してきた内容を書き出していきます。
基本的には自分自身でわかるような内容になりますので、ご容赦ください。
また、誤っている点がありましたら、コメントにてご指摘ください。

(要確認)マークがあるものは、「実行前に必ずググる」べき内容。

index

  • PHPってなんぞ?
  • echoとprintのちがいと使いどころさん!?
  • 四則演算処理
  • 文字列と数値
  • 変数と定数
    • 変数
    • 定数

PHPってなんぞ?

PHPはHTMLに埋め込むことができ、Web開発でよく使用されるスクリプト言語
※JavaScriptもスクリプト言語であり、PHPとJavaScriptの大きな違いは、そのコードがどこで実行されるかだぞ。

JavaScript
クライアントサイド(Webサイトを閲覧しているブラウザ)がコードを受け取り、そこで動作する。
そのため、どのようなコードが書かれているのか、誰でもみれる?。

PHP
サーバーサイドでコードを実行。
クライアントサイドはその結果のみを受け取るため、どのようなコードで導き出された結果なのか見ることができません?。

PHPはHTMLに埋め込んで使うことができ、<?php 〜 ?>の中にPHPの命令を書くぞ。
(<?php 〜 ?>の部分がHTMLに変換された上で表示される。)

PHPでは文末にセミコロン「;」を使って文を区切る。エラーが起きるぞー♫
あと、「//」から行末まではコメントになる。動作には関係しない情報で、主にメモなどを書き込むときに使うぞ。

xxx.php
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>xxx</title>
  <link rel="stylesheet" type="text/css" href="stylesheet.css">
</head>
<body>

<?php
print "hello,world!"; //結果 hello,world!
?>

</body>
</html>

echoとprintのちがいと使いどころさん!?

「echo」と「print」について、違いがある

「echo」は文字列などを出力するための命令。
「print」も文字列などを出力するための命令。

最も大きなちがいは式( expression )かどうか。
「echo」をif文の中に入れることはできないけど、「print」の場合は可能だよ。って感じ。

xxx.php
//print
//文字列を出力する場合はシングルクォーテーション「'」かダブルクォーテーション「"」で囲む。
print "hello,world!"; //結果 hello,world!

//echo
//文字列を出力する場合はシングルクォーテーション「'」かダブルクォーテーション「"」で囲む。
echo "hello,world!"; //結果 hello,world!



// echo の場合: ×
// Parse error になる
if (echo 5) {
    print 'echo is an expression with return value';
}
// print の場合: ○
// 問題なく動作する
if (print 5) {
    print 'print is an expression with return value';
}

四則演算処理

xxx.php
echo 3 + 2; //結果 5

echo 3 - 2; //結果 1

echo 3 * 2; //結果 6

echo 9 / 3; //結果 3

//割り算の余り
echo 5 % 2; //結果 1

文字列と数値

PHPには、「文字列」や「数値」などのデータの種類がある。
「'Hello'」,「'a'」などは文字列、「1」,「3.14」などは数値となります。

xxx.php
echo 3 + 2; //結果 5
echo "3 + 2"; //結果 3 + 2

変数と定数

変数

プログラミングの重要な概念であり楽しい部分!
変数とは、データの入れ物。頭に「$」記号をつけることによって変数を定義できるぞ。
「$変数名 = 値;」で様々な値を変数に入れることが出来ます。
「=」はプログラミングの世界では、右辺を左辺に代入するという意味ということに注意!

変数の主なルール

・変数名はドル記号から始まります。
・変数名は大文字と小文字を区別します。(ドルaとドルAは別の変数だと認識されます。)
・変数名に使えるのは、以下の文字になります。
 ・英大文字小文字(a~zもしくはA~Z)
 ・数字(ただし、先頭には使えません。)
 ・_(アンダーバー)

xxx.php
$name = hoge;
echo $name; //結果 hoge

$x = 7;
$area = $x * $x;
echo $area; //結果 49(正方形の計算)
具体例 理由
数字開始 1nam エラー出る
ローマ字 aisatu わかりにくい
日本語 名前 プログラミングでは日本語はあまりよろしくない

以下の特殊な変数名はすでに定義されています。(同じ名前は付けられません)
詳しくはこちら

変数名
$this
$GLOBALS
$_SERVER
$_GET
$_POST
$_COOKIE
$_FILES
$_SESSION

※変数は、中に入っている値を変更することもできます。
変数に、その後再び値を代入すると、後で代入した値によって変数の中身が上書きされます。

xxx.php
$num = 3;
echo $nam //結果 3

$num = 5;
echo $nam //結果 5

「変数の値にxを足したい」とき

xxx.php
$x = 1;

$x = $x + 10;
echo $x; //結果 11

//省略形
$x += 10;
$x -= 10;
$x *= 10;
$x /= 10;
$x %= 10;

//足す数字が1の時のみ
$x++
$x--

//++を変数の前に書くとその行の命令が実行される前に足される
//++を変数の後に書くとその行の命令が実行された後に足されます
$x = 3;
$y = 3;

echo ++$x; //結果 4
echo ++$y; //結果 3

文字列の連結

・・・

定数

定数も同じくデータ(値)を入れる箱のようなもの。
定数に値を入れる(定義する)には、defineという関数を使用。
(ここでは超ざっくり「命令するもの」のイメージでOK)

定数のルール

・定数は、先頭にドル記号($)が必要ありません。
・定数を定義することができるのは、define関数 のみです。(単なる代入(=)による定義はできません。)
・定数は一度設定されると再定義または未定義とすることはできません。
・定数に指定できるのは、スカラデータ(値) (型がboolean, integer, double, string, NULL) のみです。

xxx.php
define("TITLE", " 基礎メモ");

define("TITLE", "タイトル");  //再定義はできないので、これは定義されないぞ

define ("TAX" , 1.08); //消費税などで活用できそう♫
print 100 * TAX; //結果 108

更新 あんど 修正中・・・

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

laravel6.0でphp artisan migrateコマンドを打つとSQLSTATE[HY000] [1045]エラー

執筆背景

どうも、直人と申します。

現在、自分はlaravelの学習を兼ねて簡単なアプリを作成しようと試みています。

その第一段階として、
昨日VirtualBoxとVagrantを使用してlaravelの開発環境を構築し終えた。

なので、
今日はMVCモデルの学習とMySQL上のデータベースにテーブルを作成し、そこから値を拾ってきて表示するところまでを終わらせよう
と考えていた。

MVCモデルについて一通り学習を終え早速テーブルを作成しようと以下のコマンドを打つ。

$ php artisan make:migration create_books_table

create_books_taqble.phpが作成されるので、ファイル内の以下の部分をデフォルトから変更した。

create_books_taqble.php
 Schema::create('books', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('image');
            $table->string('author');
            $table->string('local');
            $table->timestamps();
        });

その後、テーブルを作成しようと

$ php artisan migrate

コマンドを実行すると、以下のエラーが発生した。

   Illuminate\Database\QueryException 

  SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost' (using password: YES) (SQL: select * from information_schema.tables where table_schema = Homestead and table_name = migrations and table_type = 'BASE TABLE')

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

      +34 vendor frames 
  35  artisan:37
      Illuminate\Foundation\Console\Kernel::handle()

何故かアクセスが拒否された。
これについての対処方法を以下で述べる。

結論

laravel5.8以降の.envファイル(データベースにアクセスするためのパスワードとか設定されてる)では、
#を文字として認識しない仕様であり、私が設定していたパスワードには#が使われていたため、パスワードをダブルクォーテーションで括ることでmigrateすることができた。

作業内容

以下では、実際の作業内容を綴っていきます。

PHPのバージョンの違いを疑う

ホスト側のPHPとゲスト側のPHPのバージョンが異なるために不具合が生じているのではないかと考え両者のバージョンを確認してみると異なることを確認した。

#ホスト側
$ php -v
PHP 7.1.23 (cli) (built: Feb 22 2019 22:19:32) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2018 Zend Technologies
#ゲスト側
$ php -v
PHP 7.4.4 (cli) (built: Mar 19 2020 20:12:35) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.4, Copyright (c), by Zend Technologies

そのため、ホスト側のPHPのバージョンをアップグレードすることにした。
具体的には、brewでインストールしたのち、パスを通して再起動するということを行なっている。

$ brew install php@7.4
$ echo 'export PATH="/usr/local/opt/php@7.4/bin:$PATH"' >> ~/.bash_profile
$ echo 'export PATH="/usr/local/opt/php@7.4/sbin:$PATH"' >> ~/.bash_profile
$ brew services start php

結果、直らなかった…。

デフォルトで作成されるrootユーザを疑う

$ mysql -u root -p

上記の方法であれば、mysqlに接続することができた(パスワードは.envファイルに記載されているものと同じ)。

mysql -u root -pで入力したユーザ名とパスワードは.envファイルに記載されていた同じなのに、何故php artisan migrateコマンドからではアクセスが拒否されたのか
ということに着目し調べてみることにした。

mysqlからuserの一覧を表示すると、デフォルトで作成されたと思われるroot@0.0.0.0ユーザと自分で作ったroot@localhostの二種類が存在することが判明。

これが原因ではないかと思い、デフォルトで作成されているroot@0.0.0.0ユーザを削除してみることにした。

#変更前
mysql> SELECT Host, User FROM mysql.user;
+-----------+------------------+
| Host      | User             |
+-----------+------------------+
| 0.0.0.0   | root             |
| localhost | root             |
+-----------+------------------+
#変更後
mysql> drop user root@0.0.0.0;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT Host, User FROM mysql.user;
+-----------+------------------+
| Host      | User             |
+-----------+------------------+
| localhost | root             |
+-----------+------------------+

しかしながら直らなかった…。

laravel本体を疑う

さらに色々深く調べてみると以下の記事を発見。
https://qiita.com/kotatsu0715/items/a8d3a93c4a46ca925fc4

要約すると、
laravel5.8以降の.envファイルでは#を文字として認識しないため、パスワードに#を使っている人はダブルクォーテーションを使いましょう
というものだった。

私のデータベースのパスワードには見事に#が使われていたため、試しにダブルクォーテーションで括ってテーブルの作成を再実行してみた。

.env
DB_PASSWORD="hoge#"
php artisan migrate
Migration table created successfully.

うまくいった!

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

laravel6.0でphp artisan migrateコマンドを打つとSQLSTATE[HY000] [1045]エラーで苦しんだ人の記録

執筆背景

どうも、直人と申します。

現在、自分はlaravelの学習を兼ねて簡単なアプリを作成しようと試みています。

その第一段階として、
昨日VirtualBoxとVagrantを使用してlaravelの開発環境を構築し終えた。

なので、
今日はMVCモデルの学習とMySQL上のデータベースにテーブルを作成し、そこから値を拾ってきて表示するところまでを終わらせよう
と考えていた。

MVCモデルについて一通り学習を終え早速テーブルを作成しようと以下のコマンドを打つ。

$ php artisan make:migration create_books_table

create_books_taqble.phpが作成されるので、ファイル内の以下の部分をデフォルトから変更した。

create_books_taqble.php
 Schema::create('books', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('image');
            $table->string('author');
            $table->string('local');
            $table->timestamps();
        });

その後、テーブルを作成しようと

$ php artisan migrate

コマンドを実行すると、以下のエラーが発生した。

   Illuminate\Database\QueryException 

  SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost' (using password: YES) (SQL: select * from information_schema.tables where table_schema = Homestead and table_name = migrations and table_type = 'BASE TABLE')

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

      +34 vendor frames 
  35  artisan:37
      Illuminate\Foundation\Console\Kernel::handle()

何故かアクセスが拒否された。
これについての対処方法を以下で述べる。

結論

laravel5.8以降の.envファイル(データベースにアクセスするためのパスワードとか設定されてる)では、
#を文字として認識しない仕様であり、私が設定していたパスワードには#が使われていたため、パスワードをダブルクォーテーションで括ることでmigrateすることができた。

作業内容

以下では、実際の作業内容を綴っていきます。

PHPのバージョンの違いを疑う

ホスト側のPHPとゲスト側のPHPのバージョンが異なるために不具合が生じているのではないかと考え両者のバージョンを確認してみると異なることを確認した。

#ホスト側
$ php -v
PHP 7.1.23 (cli) (built: Feb 22 2019 22:19:32) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2018 Zend Technologies
#ゲスト側
$ php -v
PHP 7.4.4 (cli) (built: Mar 19 2020 20:12:35) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.4, Copyright (c), by Zend Technologies

そのため、ホスト側のPHPのバージョンをアップグレードすることにした。
具体的には、brewでインストールしたのち、パスを通して再起動するということを行なっている。

$ brew install php@7.4
$ echo 'export PATH="/usr/local/opt/php@7.4/bin:$PATH"' >> ~/.bash_profile
$ echo 'export PATH="/usr/local/opt/php@7.4/sbin:$PATH"' >> ~/.bash_profile
$ brew services start php

結果、直らなかった…。

デフォルトで作成されるrootユーザを疑う

$ mysql -u root -p

上記の方法であれば、mysqlに接続することができた(パスワードは.envファイルに記載されているものと同じ)。

mysql -u root -pで入力したユーザ名とパスワードは.envファイルに記載されていた同じなのに、何故php artisan migrateコマンドからではアクセスが拒否されたのか
ということに着目し調べてみることにした。

mysqlからuserの一覧を表示すると、デフォルトで作成されたと思われるroot@0.0.0.0ユーザと自分で作ったroot@localhostの二種類が存在することが判明。

これが原因ではないかと思い、デフォルトで作成されているroot@0.0.0.0ユーザを削除してみることにした。

#変更前
mysql> SELECT Host, User FROM mysql.user;
+-----------+------------------+
| Host      | User             |
+-----------+------------------+
| 0.0.0.0   | root             |
| localhost | root             |
+-----------+------------------+
#変更後
mysql> drop user root@0.0.0.0;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT Host, User FROM mysql.user;
+-----------+------------------+
| Host      | User             |
+-----------+------------------+
| localhost | root             |
+-----------+------------------+

しかしながら直らなかった…。

laravel本体を疑う

さらに色々深く調べてみると以下の記事を発見。
https://qiita.com/kotatsu0715/items/a8d3a93c4a46ca925fc4

要約すると、
laravel5.8以降の.envファイルでは#を文字として認識しないため、パスワードに#を使っている人はダブルクォーテーションを使いましょう
というものだった。

私のデータベースのパスワードには見事に#が使われていたため、試しにダブルクォーテーションで括ってテーブルの作成を再実行してみた。

.env
DB_PASSWORD="hoge#"
php artisan migrate
Migration table created successfully.

うまくいった!

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

laravel5.5で画像アップロード方法

表題の通りです。
画像ファイルをアップロードして、アプリ内で表示させたいと思います。
初心者なりに頑張ってみました。

やりたいこと

プロフィール用の画像をアップロードして、表示させたい。

画像ファイル用DB

今回は既存のusersテーブルにカラムを追加して、ファイルのパスを保存します。

php artisan make:migration add_image_column_users_table --table=image

ルーティング

マイページ内で画像投稿用のフォームに移動したいので、そちらにまとめます。

web.php
Route::group(['middleware' => ['auth']],function() {
    //画像投稿フォーム表示
    Route::get('userimage', 'UserEditController@index')->name('image.index');
    //画像保存
    Route::post('userimage', 'UserEditController@upload')->name('image.upload');

コントローラー

アップロード用のコントローラーを作成したいと思います。

UserEditController.php
//画像アップロード画面を表示
    public function index()
    {
        return view('edit.user_image');
    }
UserEditController.php
//画像アップロードされた画像を保存
    public function upload(Request $request)
    {
        //バリデーション
        $this->validate($request,[
            'userimage' => 'required|image'
            ]);

        if($request->isMethod('POST'))
        {
            $path = $request->file('userimage')->store('public/img');
            $image = User::find(\Auth::id());
            $image->image = basename($path); //imageカラムに保存
            $image->save();

            return back()->with(['success' => 'ファイルを保存しました']);
        }
    }

上のコードではstorage/app/public/img/内にアップロードした画像が保存されます。

メソッドをすぐ忘れるのでメモ。
store()は一意のファイル名を自動で生成してくれる。
isMethdは公式サイト様より

リクエストメソッドの取得
また、isMethodメソッドを使えば、指定した文字列とHTTP動詞が一致するかを調べることができます。

これでなくても、

if ($request->hasFile('image'))  //hasFile()内はinput type の name属性

でも良さそう。
basenameはファイルパスを除いてファイル名のみを取り出してくれる。

ビュー

アップロードされた画像の保存場所と読み出し場所が違うそうです。
保存場所はstorage/app/public/
読み出し場所はpublic/storage/
なのでシンボリックリンクを設定します。ショートカットみたいな物らしい。

php artisan storage:link

これだけで良いとのこと。
これで読み出し場所から保存場所を参照出来るようになるそうです。というかなりました。
スクリーンショット 2020-04-02 17.25.55.png
AWSのcloud9上では、こんなのができてました。
ちなみに、上のコードではstorage/app/public/img/内にアップロードした画像が保存されます。

画像の読み出しは、

<img src="{{ asset('/storage/img/' . \Auth::user()->image) }}">

はこんな感じで読み出し。ってかこのやり方で良いのか...?
asset()はファイルまでのフルパスを生成してくれるそうです。
これはhttps通信する時にややこしいみたい。一旦勉強はまた別の機会に。

困ったこと

最初コードを組んで、なんでも良いから画像を、とのことでスクリーンショットをアップロードしようとしたところ、エラーが。

The userimage failed to upload.

めっちゃアバウトなエラーで困る。
dd($request->file('userimage'));
ってしてもfalseってなる。何しても分からなくて困ってたのですが、
phpinfo();して確認したら、PHPのファイル制限が2MBまでなんですね。知らなかった。
画像サイズ確認したら案の定超えてました。
覚えておきます。

非常に勉強になりました。
ここまで読んで頂いてありがとうございました。

こちらのサイト様を参考にさせていただきました。
Laravelで画像ファイルをアップロードするサンプル
画像アップロード(基本)
Laravelで画像をアップロードする方法
[Laravel] ユーザーのアイコン画像を投稿、表示させる機能の実装したのでメモ(画像の保存場所は?シンボリックリンクって?)
Laravelで画像ファイルを保存したい
【Laravel5.6】画像ファイルアップロードについてのポイントまとめ
本当にありがとうございます。

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

WordPressの管理画面に再利用ブロックへのリンクを追加する

執筆時のバージョン WordPress 5.4 “Adderley”

再利用ブロックの一覧ページがあるのはご存知?

再利用ブロック便利ですよね。

ひとつ書き換えるだけで全部変更できますし。

知らなかった方は自分のWordPressサイトにログインした状態でこのURLを編集してアクセスしてみてください。

https://あなたのどめいん/wp-admin/edit.php?post_type=wp_block

間違って消してしまった再利用ブロックもこのページのゴミ箱から復活させることもできます。安心設計。

でも……

再利用ブロックの一覧ページに行くのが面倒くさい

WordPressで再利用ブロックを編集したいときと思った時
投稿の編集を開いて⊕(ブロックの追加)から再利用可能→すべての再利用ブロックを管理
って作業を毎回してませんか?

僕はしていました

そんな方は
・テーマ・子テーマのfunctions.php
・プラグインでカスタマイズしている方はプラグインに
以下のコードを追加すると幸せになれるかもしれません(*´ω`*)

functions.phpの編集はお気をつけて!
必ずバックアップをとってから編集してください。
くれぐれもご注意ください。

functions.php
/**
 *再利用ブロックへのリンクを追加
 */
function add_reuse() {
  add_menu_page( '再利用ブロック', '再利用ブロック', 'manage_options','edit.php?post_type=wp_block' , '', 'dashicons-controls-repeat', '98.9');
}
add_action('admin_menu', 'add_reuse');

コードの利用の結果生じた損害に関するいかなる責任も負いません。

再利用ブロック.png

こんな感じになるはずです、お試しあれ!

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

WindowsにPHPのバージョン管理ツールを導入する。

2020年 4月 執筆

背景

いままでWindows10に直にPHP最新版をインストールしていましたが、
ダウングレードを行う必要があったので、バージョン管理ツールを導入することにしました。
せっかくなので、手順を簡潔にまとめました。

当記事は、Scoopというバージョン管理ツールを導入し、PHPのバージョン切り替えができるようになるまでの手順のメモになります。

※当記事ではコマンドラインツールを使用します。特にこだわりのない方は、Windows標準搭載の PowerShell というツールを使うといいと思います。

※Node.jsをはじめ、PHP以外の言語でも対応できるものがあるようですが、当記事ではPHPのバージョン管理のみを目的としています。他言語の場合、意図したバージョンに対応していない場合もあるそうです。

手順1. PHPをアンインストール

すでにPHPをインストール済みの場合、Scoop経由で導入したPHPと競合する恐れがあるので、削除したほうが無難です。

PHPのインストーラがある場合
1. インストールをダブルクリックして「uninstall」を押す。

PHPのインストーラがない&コントロールパネルの一覧に表示されている場合
1. コントロールパネル > プログラムのアンインストールまたは変更 へ移動する。
2. PHP関連のものを削除する。

PHPのインストーラがない&コントロールパネルの一覧に表示されていない場合
1. コマンドラインツールを立ち上げる。
2. gcm php | flと入力し、php.exeのパスを調べる。(whichコマンドは使えなかったので)
3. php.exeが入っているフォルダを削除する。
4. C:\Windows 配下に php.ini やdll関連ファイルがあれば、それも削除する。

手順2. Scoopをインストール

コマンドラインツールを立ち上げScoopをインストールする。

PowerShell
iex (new-object net.webclient).downloadstring('https://get.scoop.sh')

ここで

PowerShell
PowerShell requires an execution policy of 'RemoteSigned' to run Scoop.
To make this change please run:
'Set-ExecutionPolicy RemoteSigned -scope CurrentUser'

というエラーが発生する場合は、エラーメッセージに記載のあるコマンド叩いて、再びインストールを試みてください。

PowerShell
Set-ExecutionPolicy RemoteSigned -scope CurrentUser

手順3. Scoopで過去バージョンのインストールをできるようにする

過去バージョンをインストールできるようにするため、
versionsというバケットを追加する。

PowerShell
scoop bucket add versions

手順4. 任意のバージョンのPHPをインストールする

scoop searchコマンドで、インストール可能なバージョンを確認する。

PowerShell
scoop search php

'main' bucket:という項目に最新バージョン、
'varsions'bucket:という項目に過去バージョンが表示される。

scoop installコマンドを使用して、任意のバージョンのPHPをインストールする。

PowerShell
scoop install php php55 php71

(複数インストールする場合は、上のように半角スペースで区切れば複数指定可能)

手順5. PHPのバージョンを切り替える

scoop resetコマンドで、任意のバージョンに切り替える。

PowerShell
scoop reset php71

補足. PHPの設定ファイルを確認/作成する。

確認
設定ファイルを確認する場合は
C:\Users\ユーザー名\scoop\persist\php\cli\php.iniを確認する。
(非常に長いファイルなので、コマンドラインに出力するよりも、GUI(エクスプローラー)上で確認するか、PowerShellにvimを導入して編集モードで展開した方がよいです。)

作成
設定ファイルを作成する場合は
C:\Users\ユーザー名\scoop\persist\php\cli\conf.dに、任意の名前の .ini ファイルを作成する。

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

LaravelでDBに入っている値がURL文字列かどうか調べる

URLかどうかなんてDBに入れる前にフォームバリデーションで調べれば良いような気はしますが、それだとお客さんの要件にかなわないこともあるのです。つらい。

鬼の正規表現で調べても良いのですけど、そもそもLaravelにはURL文字列かどうか調べる機能はあるし、自力で鬼の正規表現を書くよりイケてる判定ができそうな気がするので、そいつを利用させてもらいたいものです。

基本的にバリデーションはRequestクラスをベースにしたRequestに面倒見させて、Controller側ではそいつをDIするってのが筋の良い書き方だとは思うのですが、そうじゃない使い方もできます。

Validatorインスタンスをmakeしようぜ

ちょっと長いのですが、実はこんな感じにするとValidatorは作れるのです。

// なんかDBのデータ取ってくる。こいつはurlというvarcharのカラムを持っていることとする。
$hoge_model = HogeModel::find($id);

// Validator::makeの第一引数は配列しか受けられないのでtoArrayしておく
$validator = Validator::make($hoge_model->toArray(), [
    'url' => 'url'
]);

こんな感じにするとValidatorインスタンスを作ることができます。
第2引数は君らの好きなバリデーションルールです。

あとは

$validator->fails()

でバリデーションがしくじってたら true が返ってきます。つまりちゃんとURL文字列であれば false になるってことですね!

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

え? print true ? '①' : true ? '②' : '③'; って正解は①じゃないの?

答え

php >  print true ? '①' : true ? '②' : '③';

もちろんみなさんは正解は②だとすぐわかったと思いますが、
私は、①になると思っていて、バグフィックスで30分くらいハマりました?

社内でもアンケートをとったら予想外だと思った人が3人/4人いたので、意外と混乱しやすい書き方だと思います。
Slack___developers_chatting___m_a_cloud___1_個の新しいアイテム.png

解説

処理の順番がわかるようにカッコをつけるとこうなります。

print (true ? '①' : true) ? '②' : '③';
  1. (true ? '①' : true)が評価されて'①'になる。
  2. '①' ? '②' : '③'こうなる。
  3. '①'trueと評価される (参考 PHP 型の比較表 https://www.php.net/manual/ja/types.comparisons.php)
  4. true ? '②' : '③'になる
  5. になる

①だと思った人の頭の中

print true ? '①' : (true ? '②' : '③');

まとめ

  • 三項演算子ネストすると混乱する人が出てくる?‍♂️
  • 括弧つける、インデントをつける、if文にする など工夫して読みやすくしよう
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PHP if, isset, emptyの真偽の判定について if()

条件分岐の基本的なところでつまづいたので、if,isset,emptyの挙動について簡単にまとめてみます。

配列$arrayをif, isset, empty それぞれで出力してみました。
$array = [0, '0', 10, false, true, null, '', [] ];


foreach($array as $val){
  if($val){echo "truthy";}
  if(!$val){echo "falsy";}
  echo "\n";
}

foreach($array as $val){
  if(isset($val)){echo "truthy";}
  if(!isset($val)){echo "falsy";}
  echo "\n";
}

foreach($array as $val){
  if(empty($val)){echo "truthy";}
  if(!empty($val)){echo "falsy";}
  echo "\n";
} 

結果
$array = [
  0,            //[if]→falsy      [isset]→truthy      [empty]→truthy
  '0',          //[if]→falsy      [isset]→truthy      [empty]→truthy
  10,           //[if]→truthy     [isset]→truthy      [empty]→falsy
  false,        //[if]→falsy      [isset]→truthy      [empty]→truthy
  true,         //[if]→truthy     [isset]→truthy      [empty]→falsy
  null,         //[if]→falsy      [isset]→falsy       [empty]→truthy
  '' ,          //[if]→falsy      [isset]→truthy      [empty]→truthy
  []            //[if]→falsy      [isset]→truthy      [empty]→truthy
];

まとめ

この結果から、例えばif文で「何かしらの数値(0や'0'を含む)が入った状態を"真"としたい場合」などのときは、(==, !=, ===, !==)を使って比較してあげる必要がある、といったところが注意点でしょうか。

基礎的な部分ですが見落としがちで、気が付きにくいエラーの原因にもなりそうなので、簡単にまとめてみました。

他にも注意点や内容のご指摘あればご教授していただけると喜びます。
以上です。

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

特定の数字やアルファベットを有する配列の生成 range()関数

指定した範囲の要素を持つ配列の生成にはrange()関数を使用します。

dice.php
$dice = range(1, 6);

var_dump($dice);

↓実行結果

dice.php
array(6) { [0]=> int(1) [1]=> int(2) [2]=> int(3) [3]=> int(4) [4]=> int(5) [5]=> int(6) }

このように引数に指定した範囲の値を持つ配列の生成が出来ます。
数字以外にも、

abc.php
$alphabet = range('a', 'z');

var_dump($alphabet);

↓実行結果

abc.php
array(26) { [0]=> string(1) "a" [1]=> string(1) "b" [2]=> string(1) "c" [3]=> string(1) "d" [4]=> string(1) "e" [5]=> string(1) "f" [6]=> string(1) "g" [7]=> string(1) "h" [8]=> string(1) "i" [9]=> string(1) "j" [10]=> string(1) "k" [11]=> string(1) "l" [12]=> string(1) "m" [13]=> string(1) "n" [14]=> string(1) "o" [15]=> string(1) "p" [16]=> string(1) "q" [17]=> string(1) "r" [18]=> string(1) "s" [19]=> string(1) "t" [20]=> string(1) "u" [21]=> string(1) "v" [22]=> string(1) "w" [23]=> string(1) "x" [24]=> string(1) "y" [25]=> string(1) "z" }

と、アルファベットでも可能です。

これは、アスキーコード(ASCIIコード)に則って生成されるものであるため、数字やアルファベットの他に記号などには対応しても、平仮名などには対応していません。

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

多次元配列について

配列の中のキーを配列として格納することが可能。

meet.php
$meet = array(
    '鶏肉'=> array(
        'price' => 68,
        'stock' => 10),

    '豚肉' => array(
        'price' => 89,
        'stock' => 15),

    '牛肉' => array(
        'price' => 128,
        'stock' => 8)
        );
foreach($meet as $name => $value) {
    echo $name . 'は、100グラム' . $value['price'] . '円、在庫は' . $value['stock'] . '個です。' . '<br>'; 
}

↓実行結果

meet.php
鶏肉は、100グラム68円在庫は10個です
豚肉は、100グラム89円在庫は15個です
牛肉は、100グラム128円在庫は8個です

複雑な構造を持つデータの配列として定義することが出来ます。

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

if文の省略記法

from.php
$area = '京都';

//A
$from = isset($area) ? '出身は' . $area . 'です' : '出身地が設定されてません';

//B
if (isset($area)) {
    $from = '出身は' . $area . 'です';
} else {
    $from = ',出身地が設定されてません';
}

Aの書き方とBの書き方ではどちらも同じ結果が$fromに代入されることになります。
初学者の自分はBの表記法でしかしたことなかったですが、Aの表記法の方が断然すっきりしますね。

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

複数行にまたがる文字列を利用する方法(ヒアドキュメント)

シングルクオートとダブルクオート以外で、複数行にまたがる文字列を利用する方法でヒアドキュメントがあります。
ヒアドキュメント構文(<<<)の後に終端識別子を定義し、それが出現するまでを文字列として認識します。

heredocument.php
$age = 29;

$a = <<<EOM
初めまして。私はktktと言います。
年齢は${age}歳です。

よろしくお願いします。
EOM;

echo $a;

実行結果

heredocument.php
初めまして私はktktと言います 年齢は29歳です よろしくお願いします

注意する点は、終端識別子は必ず行頭から始まり、直前にインデントなどを含めず、すぐに改行しなければなりません。

また、ヒアドキュメントの中ではダブルクオートと同様に、変数が展開されます。

*終端識別子は何でもよく、ABCでも大丈夫です。よく使われるのは、EOM(エンドオブメッセージ)、EOD(エンドオブドキュメント)のようです。

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

dump()やdd()をグローバルに使えるようにする

Twitterで見かけたこの記事を読んで知ったのですが、その紹介です。

LaravelやSymfonyを使っている方はdumpddを使う機会が結構あると思います。便利ですよね。var_dumpprint_r?なにそれおいしry

しかしLaravelやSymfonyの外でやろうとするとちょっと面倒です。これだけのためにわざわざsymfony/var-dumperをrequireすることもしばしば。しかしもう必要ありません。めっちゃシンプルに常に(psyshコンソールの中でも!)この機能をプリロードする方法を見つけました。 (元記事の方が)

PHPにビルトインされているauto_prepend_fileオプションを使います。

なお、元記事の著者はAlgoliaの中の人のようですが、この方法を1年以上使っていて特に問題は起こっていないとのこと。("function already defined"とか)

手順

1: 適当なところにディレクトリを作る (dotfiles/の下とか?)

2: そのディレクトリの中でcomposer require symfony/var-dumper

3: prepend.phpなどの適当なファイルを作る

prepend.php
<?php
require_once 'vendor/autoload.php';

4: php.iniの以下の箇所に絶対パスを追加

; Automatically add files before PHP document.
; http://php.net/auto-prepend-file
auto_prepend_file = /absolute/path/to/your/prepend.php

5: 以上!いつでもどこでもdump ddできるよ!

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

Laravel 5.5 でのパスワードリセット方法

Laravel 5.5パスワードリセットの機能を実装するのに結構苦労したので、
メモとして残させてもらいます。
間違ってるところもあると思いますので、何かあればご指摘いただければ嬉しいです。

やりたい事

laravelでパスワードリセット機能を実装する。
パスワード忘れてログインできない!って時に使うやつ。

migrate

php artisan migrate

認証機能

php artisan make:auth

以上で大半の準備が完了です。
必要なコントローラーはapp/http/controllers/auth/
ビューはresources/views/auth/passwords/
ルーティングにも

web.php
Auth::routes()
Route::get('/home', 'HomeController@index')->name('home');

みたいなのが追加されます。

mailableクラス作成

php artisan make:mail ResetPasswordMail

作成されたのはapp/Mail/以下にあります。

パスワードリセットのルーティング本体

vendor/laravel/framework/src/Illuminate/Routing/Router.php
// Password Reset Routes...
$this->get('password/reset', 'Auth\ForgotPasswordController@showLinkRequestForm')->name('password.request');
$this->post('password/email', 'Auth\ForgotPasswordController@sendResetLinkEmail')->name('password.email');
$this->get('password/reset/{token}', 'Auth\ResetPasswordController@showResetForm')->name('password.reset');
$this->post('password/reset', 'Auth\ResetPasswordController@reset');

1131行目ぐらいに書いてます。これをそのまま利用すればmake::auth しなくても良いのかも?

環境設定

.envファイルの中のメール送信設定を変更します。

MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

laravel/config/mail.php
にドライバの設定がありますが、envファイル変更してたら大丈夫?
メールの送信元を設定できますが、デフォルトでは無いため、直接記述します。
一旦はこんな感じに。

MAIL_FROM_ADDRESS=passreset@laraveltest.com
MAIL_FROM_NAME=Laraveler

あとはこちらのサイト様を思いっきり参考にさせて頂いて、メール設定をしました。
https://www.ritolab.com/entry/38
テスト用メールの中身を確認しながら作成していきます。

メール送信

今回はGmailを使ってみます。

MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=xxxxxxxxxxx@gmail.com
MAIL_PASSWORD=xxxxxxxxxxxxxxxx
MAIL_ENCRYPTION=tls

MAIL_FROM_ADDRESS=notif@laravelmailsender.com
MAIL_FROM_NAME=LaravelMailSender

この「MAIL_PASSWORD」ですが、実際にGmailを利用してメール送信するなら、アカウントにログインさせた状態にしないといけないって事なので、Gmailの2段階認証のところのアプリ固有パスワードを取得して設定します。
こちらを思いっきり参考にさせていただきました。
https://qiita.com/zaburo/items/37f28f0b621cbac74d15
https://qiita.com/t-kuni/items/aa906cd07e54037a5eaf

メールで送られてきたリンクの調整

Gmailからリンク付きでメールが送信されてきました。
ですが、リンクを踏んだらなぜかlocalhostにアクセスしようとしてる。
現在、某プログラミングスクールでAWSのcloud9を利用してるので、だめですね。
スクリーンショット 2020-04-02 0.03.30.png
先ほどの参考サイト様によると、

ResetPassword.php
        ->action(Lang::getFromJson('Reset Password'), url(config('app.url').route('password.reset', $this->token, false)))
        ->line(Lang::getFromJson('If you did not request a password reset, no further action is required.'));

のところにconfig('app.url')と書いてます。
ここかなぁ・・・ .envファイルの上の方に、

APP_URL=http://localhost

とあります。

…あとはすみませんがまた後日どこかのサーバーにアップロードして動作確認してみます。
そのあと記事を書き直します。
一旦はここまで。中途半端ですみません。

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