- 投稿日:2021-01-23T23:51:44+09:00
PHP ログイン認証の作成手順③ 〜新規登録機能作成②とパスワードハッシュ化〜
新規登録フォームからPOSTで送られてきたデータをデータベースにINSERTする
手順
ユーザを登録する処理
register.phpでバリデーションに引っかからずに登録ができる準備が整った時の処理をコーディングしていく。
UserLogicクラスを作成し、その中のcreateUserメソッドを作成し、それを使用する。
createUserメソッドはtrueかfalseを返すような関数だから、新規登録に失敗した時には、
$err配列に格納して、バリデーションと同じようにエラー項目として表示させる。register.php<?php require_once('../classes/UserLogic.php'); // エラーメッセージ $err = []; // バリデーション if(!$username = filter_input(INPUT_POST, 'username')){ $err[] = 'ユーザ名を記入してください'; } if(!$email = filter_input(INPUT_POST, 'email')){ $err[] = 'メールアドレスを記入してください'; } $password = filter_input(INPUT_POST, 'password'); // 正規表現 if(!preg_match("/\A[a-z\d]{8,100}+\z/i", $password)){ $err[] = 'パスワードは英数字8文字以上100文字以下にしてください。'; } $password_conf = filter_input(INPUT_POST, 'password_conf'); if($password !== $password_conf){ $err[] = '確認用パスワードと異なっています'; } if(count($err) === 0){ //ユーザを登録する処理 $hasCreated = UserLogic::createUser($_POST); if(!$hasCreated){ $err[] = '登録に失敗しました'; } } ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>ユーザ登録完了画面</title> </head> <body> <?php if (count($err) > 0) : ?> <!-- エラーがある場合にforeachで該当エラーを表示させる --> <?php foreach($err as $e) : ?> <p><?php echo $e ?></p> <?php endforeach; ?> <!-- $err配列に何もない=エラーがない から完了画面を表示させる --> <?php else: ?> <p>ユーザー登録が完了しました。</p> <?php endif ; ?> <a href="signup_form.php">戻る</a> </body> </html>UserLogicクラスを作成する
createUserメソッドでPOSTで送られてきたデータを引数にとる。
そして、送られてきたユーザ名、メールアドレス、パスワードを$arr配列に格納して、
prepareで用意したINSERT文のプレースホルダーに入れる。UserLogic.php<?php require_once('../dbconnect.php'); class UserLogic { /** * ユーザを登録する * @param array $userData * @return bool $result */ public static function createUser($userData) { $result = false; $sql = 'INSERT INTO users (name, email, password) VALUES (?, ?, ?)'; // ユーザデータを配列に入れる $arr = []; $arr[] = $userData['username']; $arr[] = $userData['email']; $arr[] = password_hash($userData['password'], PASSWORD_DEFAULT); try{ $stmt = connect()->prepare($sql); $result = $stmt->execute($arr); return $result; }catch(\Exception $e){ return $result; } } } ?>
- 投稿日:2021-01-23T20:31:17+09:00
PHP ログイン認証の作成手順② 〜新規登録機能作成とバリデーションの作成〜
手順
新規登録画面の作成
今回は、
ユーザ名
、メールアドレス
、パスワード
、パスワード確認
の4つのフォームを用意するsignup_form.php<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>ユーザ登録画面</title> </head> <body> <h2>ユーザ登録フォーム</h2> <form action="register.php" method="POST"> <p> <label for="username">ユーザ名:</label> <input type="text" name="username"> </p> <p> <label for="email">メールアドレス:</label> <input type="email" name="email"> </p> <p> <label for="password">パスワード:</label> <input type="password" name="password"> </p> <p> <label for="password_conf">パスワード確認:</label> <input type="password" name="password_conf"> </p> <p> <input type="submit" value="新規登録"> </p> </form> </body> </html>新規登録完了画面の作成
register.php<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>ユーザ登録完了画面</title> </head> <body> <p>ユーザー登録が完了しました。</p> <a href="signup_form.php">戻る</a> </body> </html>バリデーションの作成
入力フォームにて入力し、送信した後はregister.phpへ情報が飛んで、リンクに繋がる。
その時にregister.phpの方で、登録が完了したか、入力エラーがあるかどうかを表示させる仕組みを作成する。
なお、新規登録を完了させることができた場合の処理はのちに行う。①入力エラーが存在するフォームそれぞれに対して、エラーの文字を配列で集めていく。
②一つでもエラーの配列の要素がある場合は、あるもの全てをforeachで表示させていく。register.php<?php // エラーメッセージ $err = []; // バリデーション if(!$username = filter_input(INPUT_POST, 'username')){ $err[] = 'ユーザ名を記入してください'; } if(!$email = filter_input(INPUT_POST, 'email')){ $err[] = 'メールアドレスを記入してください'; } $password = filter_input(INPUT_POST, 'password'); // 正規表現 if(!preg_match("/\A[a-z\d]{8,100}+\z/i", $password)){ $err[] = 'パスワードは英数字8文字以上100文字以下にしてください。'; } $password_conf = filter_input(INPUT_POST, 'password_conf'); if($password !== $password_conf){ $err[] = '確認用パスワードと異なっています'; } if(count($err) === 0){ //ユーザを登録する処理 } ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>ユーザ登録完了画面</title> </head> <body> <?php if (count($err) > 0) : ?> <!-- エラーがある場合にforeachで該当エラーを表示させる --> <?php foreach($err as $e) : ?> <p><?php echo $e ?></p> <?php endforeach; ?> <!-- $err配列に何もない=エラーがない から完了画面を表示させる --> <?php else: ?> <p>ユーザー登録が完了しました。</p> <?php endif ; ?> <a href="signup_form.php">戻る</a> </body> </html>
- 投稿日:2021-01-23T19:09:52+09:00
PHP ログイン認証の作成手順① 〜データベースと接続する〜
使用環境(ローカル環境)
・MAMP
・phpMyAdminデータベース定義(使用するカラム)
・id
・name
・password手順
データベースとの接続
env.php<?php define('DB_HOST', 'localhost'); define('DB_NAME', 'user'); define('DB_USER', 'root'); define('DB_PASS', 'root'); ?>dbconnect.php<?php require_once('env.php'); function connect() { $host = DB_HOST; $db = DB_NAME; $user = DB_USER; $pass = DB_PASS; $options = [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, ]; $dsn = "mysql:host=$host;dbname=$db;charset=utf8mb4"; try{ $pdo = new PDO($dsn, $user, $pass, $options); }catch(PDOException $e){ echo 'error'. $e->getMessage(); } } ?>
- 投稿日:2021-01-23T18:25:50+09:00
【PHP 初級】配列を使いこなす➁ ~取得・検索・その他~
【PHP 初級】配列を使いこなす➀ ~宣言・初期化・追加・結合・削除~の続きです。
今回は配列から値を取得、検索する方法など、もう少し実務的な内容をまとめます。値の取得
配列から値を取り出す色んな方法を見てみます。
キーを指定して値を取り出す
どの言語も同じように、数値やキーを指定して値を取り出します。
php > $fruits = ['apple', 'grape', 'banana']; php > var_export($fruits[0]); 'apple'php > $colors = ['C1' => 'red', 'C2' => 'purple', 'C3' => 'green']; php > var_export($colors['C1']); 'red'すべての値を取り出す
array_values
https://www.php.net/manual/ja/function.array-values.php
array_values (配列)
戻り値:配列
array_values
は配列のすべての値を取り出し、数値のインデックス番号を付けた配列を返します。
【PHP】配列を使いこなす➀ ~宣言・初期化・追加・結合・削除~で紹介したように、配列の値の削除を行った後、インデックス番号を詰め直すのに利用したりします。
またarray_values
に連想配列を渡せば、配列に変換することが出来ます。php > $colors = ['C1' => 'red', 'C2' => 'purple', 'C3' => 'green']; php > var_export(array_values($colors)); array ( 0 => 'red', 1 => 'purple', 2 => 'green', )多次元配列からキーを指定して値を取り出す
array_column
https://www.php.net/manual/ja/function.array-column.php
array_column (配列, 指定するキー)
戻り値:配列
array_column
は個人的にかなり良く使うメソッドなので、ぜひ使い方を身に付けてみてください。
array_column
は多次元配列のキーを指定し、全ての値を配列で返します。php > $students = [ php > ['class' => 1, 'name' => 'tanaka', 'age' => 15], php > ['class' => 2, 'name' => 'yamamoto', 'age' => 16], php > ['class' => 1, 'name' => 'honda', 'age' => 16], php > ['class' => 3, 'name' => 'inoue', 'age' => 17], php > ]; // 学生の名前を取得 php > $students_name = array_column($students, 'name'); php > var_export($students_name); array ( 0 => 'tanaka', 1 => 'yamamoto', 2 => 'honda', 3 => 'inoue', )また第3引数を指定して、特定の値をキーにした多次元配列を生成することもできます。
array_column (配列, 指定するキー、新しい配列のキーとして指定するキー)
戻り値:配列言葉が分かりづらいですが、例を見ればすぐに理解できると思います。
php > $students = [ php > ['class' => 1, 'name' => 'tanaka', 'age' => 15], php > ['class' => 2, 'name' => 'yamamoto', 'age' => 16], php > ['class' => 1, 'name' => 'honda', 'age' => 16], php > ['class' => 3, 'name' => 'inoue', 'age' => 17], php > ]; // クラス毎に名前を取得する php > $name_by_class = array_column($students, 'name', 'class'); php > var_export($name_by_class); array ( 1 => 'honda', 2 => 'yamamoto', 3 => 'inoue', )注意点はキーが重複する場合、後ろの値で上書きされます。
そのため、クラス1はhondaくんが取得されます。名前だけでなく、学生の情報が全て取得したい場合は第2引数に
null
を指定します。php > $students = [ php > ['class' => 1, 'name' => 'tanaka', 'age' => 15], php > ['class' => 2, 'name' => 'yamamoto', 'age' => 16], php > ['class' => 1, 'name' => 'honda', 'age' => 16], php > ['class' => 3, 'name' => 'inoue', 'age' => 17], php > ]; // クラス毎に学生の情報を取得する php > $student_by_class = array_column($students, null, 'class'); php > var_export($student_by_class); array ( 1 => array ( 'class' => 1, 'name' => 'honda', 'age' => 16, ), 2 => array ( 'class' => 2, 'name' => 'yamamoto', 'age' => 16, ), 3 => array ( 'class' => 3, 'name' => 'inoue', 'age' => 17, ), )こちらもクラス1は重複するため、hondaくんの情報のみ取得されています。
多次元配列のキーでグルーピングする
上書きしないでクラス毎の全員の情報が取得したい場合は、次のような自作メソッドが必要になります。
public function groupBy($list, $key) { $ret = array(); if (is_array($list)) { foreach ($list as $val) { $ret[$val[$key]][] = $val; } } return $ret; }Utilメソッドとして定義し、どこからでも使えるようにしたら良いです。
グルーピングした結果は以下のようになります。php > $students = [ php > ['class' => 1, 'name' => 'tanaka', 'age' => 15], php > ['class' => 2, 'name' => 'yamamoto', 'age' => 16], php > ['class' => 1, 'name' => 'honda', 'age' => 16], php > ['class' => 3, 'name' => 'inoue', 'age' => 17], php > ]; // クラス毎に学生をグループ化する php > $group_by_class = groupBy($students, 'class'); php > var_export($group_by_class); array ( 1 => array ( 0 => array ( 'class' => 1, 'name' => 'tanaka', 'age' => 15, ), 1 => array ( 'class' => 1, 'name' => 'honda', 'age' => 16, ), ), 2 => array ( 0 => array ( 'class' => 2, 'name' => 'yamamoto', 'age' => 16, ), ), 3 => array ( 0 => array ( 'class' => 3, 'name' => 'inoue', 'age' => 17, ), ), )キーの取得
次はキーを取得する方法を見てみましょう。
配列の全てのキーを取得する
array_keys
https://www.php.net/manual/ja/function.array-keys.php
array_keys (配列)
戻り値:配列引数に渡した配列の全てのキーを配列にて返します。
php > $fruits_color = [ php > 'apple' => 'red', php > 'banana' => 'yellow', php > 'orange' => 'orange', php > 'cherry' => 'red', php > ]; php > var_export(array_keys($fruits_color)); array ( 0 => 'apple', 1 => 'banana', 2 => 'orange', 3 => 'cherry', )値を指定してキーを取得する
array_keys
https://www.php.net/manual/ja/function.array-keys.php
array_keys (配列, 指定する値, 型比較を行うか)
戻り値:配列指定した値に該当するキーを取得するには
array_keys
に第2引数を渡して使用します。
第3引数には値を検索する際に厳密な比較===
を行うかどうかをtrue
,false
で指定します。
常にtrue
を指定することをお勧めします。php > $fruits_color = [ php > 'apple' => 'red', php > 'banana' => 'yellow', php > 'orange' => 'orange', php > 'cherry' => 'red', php > ]; php > $red_fruits = array_keys($fruits_color, 'red', true); php > var_export($red_fruits); array ( 0 => 'apple', 1 => 'cherry', )もし第3引数に
true
を指定しない場合、以下のような想定外の動作をする可能性があります。php > $numbers = [ php > 'zero' => 0, php > 'one' => 1, php > 'two' => 2, php > ]; // 何も取得されないと思いきや、'zero'が取得される php > $number = array_keys($numbers, 'a'); php > var_export($number); array ( 0 => 'zero', )第3引数を指定しないと値の検索に緩やかな比較
==
を行います。
PHPは型が異なる値同士を比較する際に、暗黙的な型変換を行います。
そのため数値と文字列を比較しようとすると、文字列は0に変換されてしまいます。php > var_export((int) 'a'); 0なので上記のように第2引数に'a'を指定しても、実際には0に変換されてしまうので、'zero'が取得されてしまうのです。
このような想定外の動作はバグを引き起こす可能性があるため、避けるべきでしょう。値の検索
値を指定して存在するか検索する
array_search
https://www.php.net/manual/ja/function.array-search.php
array_search(検索する値, 配列, 型比較を行うか)
戻り値:キーもしくはfalse値が見つかった場合、該当のキーを返します。
見つからなかった場合はfalse
を返します。
array_keys
は値を指定した場合、該当するキーを全て配列で返しますが、array_search
は1つのキーを数値か文字列にて返します。
そのため1つ以上の値が見つかる場合は先に見つかった方のキーを返します。php > $foods = ['ramen', 'sushi', 'curry', 'udon', 'karaage', 'sushi']; // 寿司を検索。寿司は2つあるため、前方のキーが取得される。 php > $sushi_key = array_search('sushi', $foods, true); php > var_export($sushi_key); 1 // ピザを検索。値が見つからないためfalseを返す。 php > $pizza_key = array_search('pizza', $foods, true); php > var_export($pizza_key); false
array_search
も第3引数にtrue
を指定して厳密な比較を行うようにしましょう。in_array
https://www.php.net/manual/ja/function.in-array.php
in_array(検索する値, 配列, 型比較を行うか)
戻り値:trueもしくはfalse使い方は
array_search
と同じですが、値が見つかった場合にキーではなくtrue
を返します。
第3引数にはもちろんtrue
を指定します。php > $foods = ['ramen', 'sushi', 'curry', 'udon', 'karaage', 'sushi']; php > $sushi_key = in_array('sushi', $foods, true); php > var_export($sushi_key); true php > $pizza_key = in_array('pizza', $foods, true); php > var_export($pizza_key); false
array_search
とin_array
の使い分けは、
値を検索して存在する場合、その値を用いて何らかの処理をしたい時はarray_search
を$key = array_search('val', $list, true); if ($key !== false) { $value = $list[$key]; ... // 値を使って処理を行う }値を検索して存在するかしないかで何らかの処理をしたい場合は
in_array
を使うイメージです。if (in_array('val', $list, true)) { ... // 存在する場合の処理 } else { ... // 存在しない場合の処理 }キーの検索
キーを指定して存在するか検索する
array_key_exists
https://www.php.net/manual/ja/function.array-key-exists.php
array_key_exists (検索するキー, 配列)
戻り値:trueもしくはfalse第1引数に渡したキーが存在すれば
true
を返します。php > $fruits = [ php > 'name' => 'apple', 'color' => 'red', php > 'name' => 'banana', 'color' => 'yellow', php > 'name' => 'melon', 'color' => 'green', php > ]; php > var_export(array_key_exists('name', $fruits)); true php > var_export(array_key_exists('price', $fruits)); false
isset
やempty
を使ってもarray_key_exists
と同じようなことができます。isset
https://www.php.net/manual/ja/function.isset.php
isset (変数)
戻り値:trueもしくはfalse変数が宣言されていて、かつ
null
でなければtrue
を返します。php > $fruits = [ php > 'name' => 'apple', 'color' => 'red', php > 'name' => 'banana', 'color' => 'yellow', php > 'name' => 'melon', 'color' => 'green', php > ]; php > var_export(isset($fruits['name'])); true php > var_export(isset($fruits['price'])); falseempty
https://www.php.net/manual/ja/function.empty.php
empty (変数)
戻り値:trueもしくはfalse変数が宣言されていないか、空であれば
true
を返します。
array_key_exist
やisset
とは逆にキーが存在しなければtrue
を返します。
同じ使い方をしたい場合は必ず!
を付けるようにしましょう。php > $fruits = [ php > 'name' => 'apple', 'color' => 'red', php > 'name' => 'banana', 'color' => 'yellow', php > 'name' => 'melon', 'color' => 'green', php > ]; php > var_export(!empty($fruits['name'])); true php > var_export(!empty($fruits['price'])); falsearray_key_exists、isset、emptyの違い
array_key_exists
はキーが定義されているかどうかのみを判断します。
isset
はキーが定義されているか、また値がnull
ではないかを判断します。
empty
はキーが提起されているか、また値が空ではないかを判断します。いくつかの違いをまとめると以下のようになります。
key/value array_key_exists isset !empty 'a' => undefined false false false 0 => NULL true false false 1 => '' true true false 2 => 0 true true false 3 => 'val' true true true // array_key_exists php > var_export(array_key_exists('a', $list)); false php > var_export(array_key_exists(0, $list)); true php > var_export(array_key_exists(1, $list)); true php > var_export(array_key_exists(2, $list)); true php > var_export(array_key_exists(3, $list)); true // isset php > var_export(isset($list['a'])); false php > var_export(isset($list[0])); false php > var_export(isset($list[1])); true php > var_export(isset($list[2])); true php > var_export(isset($list[3])); true // empty php > var_export(!empty($list['a'])); false php > var_export(!empty($list[0])); false php > var_export(!empty($list[1])); false php > var_export(!empty($list[2])); false php > var_export(!empty($list[3])); trueキーが存在するかチェックしたい場合は
array_key_exists
を、
キーが存在して意味のある値が入っていることを確認したい場合はisset
やempty
を使いましょう。その他、配列に関する色々
JAVAのstreamぽい書き方もできる
詳細は割愛しますが、JAVAのstreamのように配列の全要素を回しながら処理する色んな関数があります。
array_walk
array_filter
array_map
など最後の要素の後にはカンマを付ける
これは賛否両論があるようですが
・1行で記述する場合は最後にカンマを付けない
・複数行で技術する場合は最後にカンマを付ける
が一般的のようです。配列を一行で定義する場合は、ふつうは最後のカンマを省略します。
つまり、 array(1, 2) のほうが array(1, 2, ) よりおすすめだということです。
しかし複数行で定義する場合は、最後のカンマをつけることが一般的です。
そうしておけば、配列の最後に要素を追加するのが容易になるからです。we encourage using a trailing comma for the last item in the array; this minimizes the impact of adding new items on successive lines, and helps to ensure no parse errors occur due to a missing comma.
$sampleArray = array(1, 2, 3, 'Zend', 'Studio'); // 最後にカンマを付けない$sampleArray = array( 1, 2, 3, 'Zend', 'Studio', $a, $b, $c, 56.44, $d, 500, // 最後にカンマを付ける );
- 投稿日:2021-01-23T18:25:50+09:00
【PHP 初級】配列おさらい➁ ~取得・検索・その他~
【PHP 初級】配列おさらい➀ ~宣言・初期化・追加・結合・削除~の続きです。
今回は配列から値を取得、検索する方法など、もう少し実務的な内容をまとめます。値の取得
配列から値を取り出す色んな方法を見てみます。
キーを指定して値を取り出す
どの言語も同じように、数値やキーを指定して値を取り出します。
php > $fruits = ['apple', 'grape', 'banana']; php > var_export($fruits[0]); 'apple'php > $colors = ['C1' => 'red', 'C2' => 'purple', 'C3' => 'green']; php > var_export($colors['C1']); 'red'すべての値を取り出す
array_values
https://www.php.net/manual/ja/function.array-values.php
array_values (配列)
戻り値:配列
array_values
は配列のすべての値を取り出し、数値のインデックス番号を付けた配列を返します。
【PHP 初級】配列おさらい➀ ~宣言・初期化・追加・結合・削除~で紹介したように、配列の値の削除を行った後、インデックス番号を詰め直すのに利用したりします。
またarray_values
に連想配列を渡せば、配列に変換することが出来ます。php > $colors = ['C1' => 'red', 'C2' => 'purple', 'C3' => 'green']; php > var_export(array_values($colors)); array ( 0 => 'red', 1 => 'purple', 2 => 'green', )多次元配列からキーを指定して値を取り出す
array_column
https://www.php.net/manual/ja/function.array-column.php
array_column (配列, 指定するキー)
戻り値:配列
array_column
は個人的にかなり良く使うメソッドなので、ぜひ使い方を身に付けてみてください。
array_column
は多次元配列のキーを指定し、全ての値を配列で返します。php > $students = [ php > ['class' => 1, 'name' => 'tanaka', 'age' => 15], php > ['class' => 2, 'name' => 'yamamoto', 'age' => 16], php > ['class' => 1, 'name' => 'honda', 'age' => 16], php > ['class' => 3, 'name' => 'inoue', 'age' => 17], php > ]; // 学生の名前を取得 php > $students_name = array_column($students, 'name'); php > var_export($students_name); array ( 0 => 'tanaka', 1 => 'yamamoto', 2 => 'honda', 3 => 'inoue', )また第3引数を指定して、特定の値をキーにした多次元配列を生成することもできます。
array_column (配列, 指定するキー、新しい配列のキーとして指定するキー)
戻り値:配列言葉が分かりづらいですが、例を見ればすぐに理解できると思います。
php > $students = [ php > ['class' => 1, 'name' => 'tanaka', 'age' => 15], php > ['class' => 2, 'name' => 'yamamoto', 'age' => 16], php > ['class' => 1, 'name' => 'honda', 'age' => 16], php > ['class' => 3, 'name' => 'inoue', 'age' => 17], php > ]; // クラス毎に名前を取得する php > $name_by_class = array_column($students, 'name', 'class'); php > var_export($name_by_class); array ( 1 => 'honda', 2 => 'yamamoto', 3 => 'inoue', )注意点はキーが重複する場合、後ろの値で上書きされます。
そのため、クラス1はhondaくんが取得されます。名前だけでなく、学生の情報が全て取得したい場合は第2引数に
null
を指定します。php > $students = [ php > ['class' => 1, 'name' => 'tanaka', 'age' => 15], php > ['class' => 2, 'name' => 'yamamoto', 'age' => 16], php > ['class' => 1, 'name' => 'honda', 'age' => 16], php > ['class' => 3, 'name' => 'inoue', 'age' => 17], php > ]; // クラス毎に学生の情報を取得する php > $student_by_class = array_column($students, null, 'class'); php > var_export($student_by_class); array ( 1 => array ( 'class' => 1, 'name' => 'honda', 'age' => 16, ), 2 => array ( 'class' => 2, 'name' => 'yamamoto', 'age' => 16, ), 3 => array ( 'class' => 3, 'name' => 'inoue', 'age' => 17, ), )こちらもクラス1は重複するため、hondaくんの情報のみ取得されています。
多次元配列のキーでグルーピングする
上書きしないでクラス毎の全員の情報が取得したい場合は、次のような自作メソッドが必要になります。
public function groupBy($list, $key) { $ret = array(); if (is_array($list)) { foreach ($list as $val) { $ret[$val[$key]][] = $val; } } return $ret; }Utilメソッドとして定義し、どこからでも使えるようにしたら良いです。
グルーピングした結果は以下のようになります。php > $students = [ php > ['class' => 1, 'name' => 'tanaka', 'age' => 15], php > ['class' => 2, 'name' => 'yamamoto', 'age' => 16], php > ['class' => 1, 'name' => 'honda', 'age' => 16], php > ['class' => 3, 'name' => 'inoue', 'age' => 17], php > ]; // クラス毎に学生をグループ化する php > $group_by_class = groupBy($students, 'class'); php > var_export($group_by_class); array ( 1 => array ( 0 => array ( 'class' => 1, 'name' => 'tanaka', 'age' => 15, ), 1 => array ( 'class' => 1, 'name' => 'honda', 'age' => 16, ), ), 2 => array ( 0 => array ( 'class' => 2, 'name' => 'yamamoto', 'age' => 16, ), ), 3 => array ( 0 => array ( 'class' => 3, 'name' => 'inoue', 'age' => 17, ), ), )キーの取得
次はキーを取得する方法を見てみましょう。
配列の全てのキーを取得する
array_keys
https://www.php.net/manual/ja/function.array-keys.php
array_keys (配列)
戻り値:配列引数に渡した配列の全てのキーを配列にて返します。
php > $fruits_color = [ php > 'apple' => 'red', php > 'banana' => 'yellow', php > 'orange' => 'orange', php > 'cherry' => 'red', php > ]; php > var_export(array_keys($fruits_color)); array ( 0 => 'apple', 1 => 'banana', 2 => 'orange', 3 => 'cherry', )値を指定してキーを取得する
array_keys
https://www.php.net/manual/ja/function.array-keys.php
array_keys (配列, 指定する値, 型比較を行うか)
戻り値:配列指定した値に該当するキーを取得するには
array_keys
に第2引数を渡して使用します。
第3引数には値を検索する際に厳密な比較===
を行うかどうかをtrue
,false
で指定します。
常にtrue
を指定することをお勧めします。php > $fruits_color = [ php > 'apple' => 'red', php > 'banana' => 'yellow', php > 'orange' => 'orange', php > 'cherry' => 'red', php > ]; php > $red_fruits = array_keys($fruits_color, 'red', true); php > var_export($red_fruits); array ( 0 => 'apple', 1 => 'cherry', )もし第3引数に
true
を指定しない場合、以下のような想定外の動作をする可能性があります。php > $numbers = [ php > 'zero' => 0, php > 'one' => 1, php > 'two' => 2, php > ]; // 何も取得されないと思いきや、'zero'が取得される php > $number = array_keys($numbers, 'a'); php > var_export($number); array ( 0 => 'zero', )第3引数を指定しないと値の検索に緩やかな比較
==
を行います。
PHPは型が異なる値同士を比較する際に、暗黙的な型変換を行います。
そのため数値と文字列を比較しようとすると、文字列は0に変換されてしまいます。php > var_export((int) 'a'); 0なので上記のように第2引数に'a'を指定しても、実際には0に変換されてしまうので、'zero'が取得されてしまうのです。
このような想定外の動作はバグを引き起こす可能性があるため、避けるべきでしょう。値の検索
値を指定して存在するか検索する
array_search
https://www.php.net/manual/ja/function.array-search.php
array_search(検索する値, 配列, 型比較を行うか)
戻り値:キーもしくはfalse値が見つかった場合、該当のキーを返します。
見つからなかった場合はfalse
を返します。
array_keys
は値を指定した場合、該当するキーを全て配列で返しますが、array_search
は1つのキーを数値か文字列にて返します。
そのため1つ以上の値が見つかる場合は先に見つかった方のキーを返します。php > $foods = ['ramen', 'sushi', 'curry', 'udon', 'karaage', 'sushi']; // 寿司を検索。寿司は2つあるため、前方のキーが取得される。 php > $sushi_key = array_search('sushi', $foods, true); php > var_export($sushi_key); 1 // ピザを検索。値が見つからないためfalseを返す。 php > $pizza_key = array_search('pizza', $foods, true); php > var_export($pizza_key); false
array_search
も第3引数にtrue
を指定して厳密な比較を行うようにしましょう。in_array
https://www.php.net/manual/ja/function.in-array.php
in_array(検索する値, 配列, 型比較を行うか)
戻り値:trueもしくはfalse使い方は
array_search
と同じですが、値が見つかった場合にキーではなくtrue
を返します。
第3引数にはもちろんtrue
を指定します。php > $foods = ['ramen', 'sushi', 'curry', 'udon', 'karaage', 'sushi']; php > $sushi_key = in_array('sushi', $foods, true); php > var_export($sushi_key); true php > $pizza_key = in_array('pizza', $foods, true); php > var_export($pizza_key); false
array_search
とin_array
の使い分けは、
値を検索して存在する場合、その値を用いて何らかの処理をしたい時はarray_search
を$key = array_search('val', $list, true); if ($key !== false) { $value = $list[$key]; ... // 値を使って処理を行う }値を検索して存在するかしないかで何らかの処理をしたい場合は
in_array
を使うイメージです。if (in_array('val', $list, true)) { ... // 存在する場合の処理 } else { ... // 存在しない場合の処理 }キーの検索
キーを指定して存在するか検索する
array_key_exists
https://www.php.net/manual/ja/function.array-key-exists.php
array_key_exists (検索するキー, 配列)
戻り値:trueもしくはfalse第1引数に渡したキーが存在すれば
true
を返します。php > $fruits = [ php > 'name' => 'apple', 'color' => 'red', php > 'name' => 'banana', 'color' => 'yellow', php > 'name' => 'melon', 'color' => 'green', php > ]; php > var_export(array_key_exists('name', $fruits)); true php > var_export(array_key_exists('price', $fruits)); false
isset
やempty
を使ってもarray_key_exists
と同じようなことができます。isset
https://www.php.net/manual/ja/function.isset.php
isset (変数)
戻り値:trueもしくはfalse変数が宣言されていて、かつ
null
でなければtrue
を返します。php > $fruits = [ php > 'name' => 'apple', 'color' => 'red', php > 'name' => 'banana', 'color' => 'yellow', php > 'name' => 'melon', 'color' => 'green', php > ]; php > var_export(isset($fruits['name'])); true php > var_export(isset($fruits['price'])); falseempty
https://www.php.net/manual/ja/function.empty.php
empty (変数)
戻り値:trueもしくはfalse変数が宣言されていないか、空であれば
true
を返します。
array_key_exist
やisset
とは逆にキーが存在しなければtrue
を返します。
同じ使い方をしたい場合は必ず!
を付けるようにしましょう。php > $fruits = [ php > 'name' => 'apple', 'color' => 'red', php > 'name' => 'banana', 'color' => 'yellow', php > 'name' => 'melon', 'color' => 'green', php > ]; php > var_export(!empty($fruits['name'])); true php > var_export(!empty($fruits['price'])); falsearray_key_exists、isset、emptyの違い
array_key_exists
はキーが定義されているかどうかのみを判断します。
isset
はキーが定義されているか、また値がnull
ではないかを判断します。
empty
はキーが提起されているか、また値が空ではないかを判断します。いくつかの違いをまとめると以下のようになります。
key/value array_key_exists isset !empty 'a' => undefined false false false 0 => NULL true false false 1 => '' true true false 2 => 0 true true false 3 => 'val' true true true // array_key_exists php > var_export(array_key_exists('a', $list)); false php > var_export(array_key_exists(0, $list)); true php > var_export(array_key_exists(1, $list)); true php > var_export(array_key_exists(2, $list)); true php > var_export(array_key_exists(3, $list)); true // isset php > var_export(isset($list['a'])); false php > var_export(isset($list[0])); false php > var_export(isset($list[1])); true php > var_export(isset($list[2])); true php > var_export(isset($list[3])); true // empty php > var_export(!empty($list['a'])); false php > var_export(!empty($list[0])); false php > var_export(!empty($list[1])); false php > var_export(!empty($list[2])); false php > var_export(!empty($list[3])); trueキーが存在するかチェックしたい場合は
array_key_exists
を、
キーが存在して意味のある値が入っていることを確認したい場合はisset
やempty
を使いましょう。その他、配列に関する色々
JAVAのstreamぽい書き方もできる
詳細は割愛しますが、JAVAのstreamのように配列の全要素を回しながら処理する色んな関数があります。
array_walkarray_walk (配列, コールバック関数, コールバック関数の引数)
戻り値:true配列を回してコールバック関数の処理を行います。
コールバック関数に渡す第1引数は配列の値、第2引数は配列のキーになります。
コールバック関数で第3引数を使用したい場合はarray_walk
に第3引数を指定します。
JAVAのstream.forEach
みたいなイメージです。array_filter (配列, コールバック関数, モード)
戻り値:配列配列を回してコールバック関数でフィルタリングした結果を配列で返します。
第3引数ではコールバック関数に何を引数として渡すかを指定します。
デフォルトだと配列の値を引数として渡します。
JAVAのstream.filter
に値します。array_map (コールバック関数, 配列...)
戻り値:配列配列を回してコールバック関数の処理を行います。
コールバック関数の処理を通った結果を配列で返します。
コールバック関数に引数で渡す配列は複数指定することが出来ます。
JAVAのstream.map
に似ています。最後の要素の後にはカンマを付ける
これは賛否両論があるようですが
・1行で記述する場合は最後にカンマを付けない
・複数行で技術する場合は最後にカンマを付ける
が一般的のようです。配列を一行で定義する場合は、ふつうは最後のカンマを省略します。
つまり、 array(1, 2) のほうが array(1, 2, ) よりおすすめだということです。
しかし複数行で定義する場合は、最後のカンマをつけることが一般的です。
そうしておけば、配列の最後に要素を追加するのが容易になるからです。we encourage using a trailing comma for the last item in the array; this minimizes the impact of adding new items on successive lines, and helps to ensure no parse errors occur due to a missing comma.
$sampleArray = array(1, 2, 3, 'Zend', 'Studio'); // 最後にカンマを付けない$sampleArray = array( 1, 2, 3, 'Zend', 'Studio', $a, $b, $c, 56.44, $d, 500, // 最後にカンマを付ける );
- 投稿日:2021-01-23T17:29:12+09:00
【PHP】初中級者が解くべき過去問精選 100 問を解いてみた【3問目/100】
アルゴリズムのアウトプット
ということで、
レッドコーダーが教える、競プロ・AtCoder上達のガイドライン【中級編:目指せ水色コーダー!】@e869120さんAtCoder で水色コーダー、つまりレーティング 1200 を少ない問題数で達成するために、茶色コーダー・緑コーダーにとって適切な教育的良問を 100 問集めました。
こちらの記事の初中級者が解くべき過去問精選 100 問
をPHPで解いていきます。<?php while (true) { <?php $wordArr = str_split(trim(fgets(STDIN))); $num = count($wordArr); $max = 0; $count = 0; $acgt = ['A', 'C', 'G', 'T']; for ($i = 0; $i < $num; $i++) { if (in_array($wordArr[$i], $acgt)) { $count++; $max = max($count, $max); } else { $count = 0; } } echo $max; }文字列を配列化し順番に該当する文字かどうか判定。
連続している間は足し上げていき、対象出ない場合はcountをリセットする問題。
- 投稿日:2021-01-23T16:15:19+09:00
【PHP】初中級者が解くべき過去問精選 100 問を解いてみた【2問目/100】
アルゴリズムのアウトプット
ということで、
レッドコーダーが教える、競プロ・AtCoder上達のガイドライン【中級編:目指せ水色コーダー!】@e869120さんAtCoder で水色コーダー、つまりレーティング 1200 を少ない問題数で達成するために、茶色コーダー・緑コーダーにとって適切な教育的良問を 100 問集めました。
こちらの記事の初中級者が解くべき過去問精選 100 問
をPHPで解いていきます。<?php $num = trim(fgets(STDIN)); $answer = 0; for ($i = 1; $i <= $num; $i++) { if ($i % 2 == 0) { continue; } $count = 0; for ($j = 1; $j <= $num; $j++) { if ($i % $j == 0) { $count++; } } if ($count == 8) { $answer++; } } echo $answer; }偶数のときはガード節使って計算量を減らすようにした。
- 投稿日:2021-01-23T15:51:37+09:00
【PHP】初中級者が解くべき過去問精選 100 問を解いてみた【1問目/100】
アルゴリズムのアウトプット
ということで、
レッドコーダーが教える、競プロ・AtCoder上達のガイドライン【中級編:目指せ水色コーダー!】@e869120さんAtCoder で水色コーダー、つまりレーティング 1200 を少ない問題数で達成するために、茶色コーダー・緑コーダーにとって適切な教育的良問を 100 問集めました。
こちらの記事の初中級者が解くべき過去問精選 100 問
をPHPで解いていきます。<?php while (true) { $s = trim(fgets(STDIN)); $s = str_replace(array("\r\n","\r","\n"), '', $s); $s = explode(" ", $s); $n = $s[0]; $x = $s[1]; if ($n == 0 && $x == 0) { break; } $ans = 0; for ($i = 1; $i <= $n; $i++) { for ($j = 1; $j <= $n; $j++) { for ($k = 1; $k <= $n; $k++) { if ($i < $j && $j < $k && $i + $j +$k == $x) { $ans++; } } } } echo $ans . "\n"; }典型的な全列挙の問題。
- 投稿日:2021-01-23T15:50:58+09:00
【超初心者編】PHP7×MySQL、PDOを使用してDB(データーベース)に接続する方法
データベースとの接続は、初心者にとって「最初の壁」
こんにちは、自分はPHPを勉強して2ヶ月目の初心者です。
今回は自分用のメモと記憶整理としてデーターベース(以降:DB)との接続方法を超簡単に説明します。環境は以下の通り
・MAMP6.2
・PHP7.4.9
・MySQL 5.7.30【注意】初心者の解説なので、専門的に学習したい人は他の学習用のサイト・ページなどを参考にしてください!
MySQLとPDOについて
MySQLはオープンソースのDB(データベース)管理システムです。
(オープンソースとは商用、非商用を問わず配布されてるもの)
・無償で利用できる
・大容量のデーターを高速で動作させられる
・幅広いOSに対応している(Windows,mac,Linuxなど)上記は特徴の一部に過ぎません。
優秀なシステムで実際に世界中の企業でも使用されています。PDOとは?
PDO(PHP Data Objects)とは、
PHPからDBへアクセスする機能を持った拡張モジュールです。なにやら難しそうですが、とりあえずDBへアクセする為の便利な機能だと思ってもらえれば、今回は大丈夫です!
接続する方法
それでは、接続方法を解説していきます。
先づはDBに接続するSQL文を用意します。~phpMyAdmin上の表記以下と仮定~
Sever:localhost8889
ユーザー名:root
パスワード:rootDB接続用のSQL文を作成
PHP7$sql = 'mysql:dbname=test;host=localhost;port=8889;charset=utf8'; $user = 'root'; $pass = 'root';変数sqlにDB接続用のsql文を代入して、
dbname、host、portの各所にDBの情報を入力します。最後のcharasetの所は、文字コードをUTF-8に指定しています。
変数userとpassにはユーザー名とパスワードを入力してください。
PDOを使いSQL文を$dbhに代入する
$dbh = new PDO($sql,$user, $id);$dbhにPDOを使い、先程の変数を組み合わせる。
例外処理を追加
もしDBとの接続が出来なかった場合、エラー文を表示する様に
try(例外処理)を追加します。try { $dbh = new PDO($sql,$user,$id); } catch(PDOException $e) { echo('DB接続エラー:' . $e->getMessage()); }これによりDBと接続出来なかった時、cath内の'DB接続エラー'とエラー文が表示されるようになります。
まとめ
MySQLなどDBの世界は本当に奥が深く、覚える事が多く難しいです。
そんな中、少しでも分かりやすく記録できたらと思い投稿させていただきました。今回はDBの接続方法のみですが、今後SELECTやINSERT、内部結合についても取り上げられたらと思います。
少しでもお役に立てたら幸いです!
- 投稿日:2021-01-23T14:51:11+09:00
【PHP】Docker環境にphpMyadminを導入する
手順
docker-compose.ymlにphpMyadominのコンテナを追記します。
docker-compose.yml#docker-compose.ymlのバージョン version: "3.8" #docker volumeの設定 volumes: docker-volume: #services以下に各コンテナの設定を書く services: #Webサーバーのコンテナ web: image: nginx:1.18 ports: - "8000:80" depends_on: - app volumes: - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf - .:/var/www/html #アプリケーションのコンテナ app: build: ./docker/php volumes: - .:/var/www/html #データベースのコンテナ db: image: mysql:5.7 ports: - "3306:3306" environment: MYSQL_DATABASE: db_name MYSQL_USER: db_user MYSQL_PASSWORD: db_password MYSQL_ROOT_PASSWORD: root TZ: "Asia/Tokyo" volumes: - docker-volume:/var/lib/mysql # phpMyadominのコンテナ作成 phpmyadmin: image: phpmyadmin/phpmyadmin depends_on: - db environment: - PMA_ARBITRARY=1 - PMA_HOSTS=db - PMA_USER=db_user - PMA_PASSWORD=db_password ports: - "8080:80" volumes: - ./docker/phpmyadmin/sessions:/sessionsコードの下部にある
# phpMyadominのコンテナ作成
からが追記する箇所です。
portsを8080に設定しているので、localhost:8080
でphpmyadminの管理画面にアクセスできるように設定しています。
また、volumesにある./docker/phpmyadmin/sessions:/sessions
ではセッション情報をボリュームに設定して永続化するようにします。補足
参考までに作ってみた環境
↓https://github.com/yuyaamano23/Laravel_Docker_practice/tree/github-open
ちなみに僕は以下の記事を参考にphp+mysql+nginxの環境を構築しました。神記事です。
絶対に失敗しないDockerでLaravel+Vueの実行環境(LEMP環境)を構築する方法〜前編〜
絶対に失敗しないDockerでLaravel6.8+Vueの実行環境(LEMP環境)を構築する方法〜後編〜
Docker Composeでphpmyadminを導入する各々構築したDocker環境のプロジェクトにあるdocker-compose.ymlnに追記していただければ良いと思います。
- 投稿日:2021-01-23T11:49:03+09:00
PHPで突如現れた「? : 」に、なんそれ!となった頃の話
めちゃめちゃ初心者だった頃、PHP Laravelでの業務中に、
先輩が書いたコードで突如現れた「? : 」に、なんそれ!となりました。開発言語がPHPなので、
「PHP ? : 」とかでググってみても、いまいちHITしなくて困った記憶があり、
同じ様な人がいるかもしれないので、記事にしてみました。早速「? : 」の正体ですが、条件演算子の中の『三項演算子』です。
AAA ? BBB : CCCこの形、
AAA が「true」なら BBB 、「false」なら CCC
ということになります。
初心者だった頃の私は、この条件分岐なら全部if文で書いてました。
example.phpif ( AAA ) { BBB } else { CCC }どっちが見やすいか、一目で分かりやすいか、と言われると、
定義する値によるため、場合によって書き分ける必要があります。条件や分岐後に定義したい内容が変数だけとかの短いものは、
「AAA ? BBB : CCC」の形がスマートだなと思います。条件演算子『三項演算子』については、PHPマニュアルにて確認しました。
https://www.php.net/manual/ja/language.operators.comparison.php最後に
この記事が「PHP ? : 」とかでググった時に出ると良いなぁと思いながら書きました。
どうなんでしょうね…届けこの想い…!
- 投稿日:2021-01-23T10:02:28+09:00
【Laravel5.5】キャッシュクリアコマンドと、まとめて実行する方法
Laravel5.5使用時の例です。
ファイルの変更を反映した後、実行しておきたいキャッシュクリアコマンド。php artisan cache:clear→「storage/framework/cache/data」内のキャッシュデータを削除する。
php artisan view:clear→「storage/framework/views」内に全ビューのキャッシュデータを削除する。
php artisan config:clear→「config」ディレクトリのファイルの更新内容が反映されるようになる。
php artisan route:clear→「bootstrap/cache/routes.php」のRouteのキャッシュデータを削除する。
※ 各コマンドで何しているかは、
https://blog.capilano-fw.com/?p=768 より引用しました。
こちらのサイトにはとてもお世話になっております。感謝永遠に。。まとめて実行するには…
systemディレクトリ直下にシェルスクリプトを作成する。
clear_cache.shphp artisan cache:clear php artisan view:clear php artisan config:clear php artisan route:clear //最後に改行を入れる上記では「clear_cache.sh」というファイル名にしているので、
systemディレクトリにいる状態で、
下記のコマンドでまとめて実行することができる。sh clear_cache.sh楽。よき。