Kintarou'sBlog

プログラミング学習中。学習内容のアウトプットや読書で学んだことなど随時投稿!

【PHP】選択した色を背景色に設定する

こんにちは😊Kintarouです。

現在エンジニア転職を目指してプログラミング学習中です👨‍🎓
夢はフリーランスエンジニアになって働く人にとって働く事が楽しくなるシステムを作ること!
と、愛する妻と海外移住すること🗽

プログラミングや読んでいる本のことなど、ブログに書いていきます!
twitter : https://twitter.com/ryosuke_angry


今回参考にさせて頂いたサイト様🙇‍♂️ dotinstall.com


選択した色を背景色にする

PHPの記述を活用すれば、下記のように選択した色を背景色にする事も出来ます。

■_header.php

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>PHP Practice</title>
</head>

#body要素のstyleにPHPを組み込んで背景色を$colorにします。
<body style="background-color: <?= h($color); ?>;">

■index.php

<?php

#$colorを選択して定義するまではデフォルト値(transparent)とします。
$color = 'transparent';

include('../app/_parts/_header.php');

?>

<form action="result.php" method="get">
  
    <label><input type="radio" name="color" value="orange">Orange</label>
    <label><input type="radio" name="color" value="pink">Pink</label>
    <label><input type="radio" name="color" value="gold">Gold</label>
  <button>Send</botton>
</form>

pinkを選択してSENDします。
f:id:ryosuke-toyama:20201104143702p:plain

■result.php

<?php

function h ($str)
{
 return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}

#GETのパラメーターを$colorとし、未選択(Null)の場合はtransparentとします。
$color = filter_input(INPUT_GET, 'color') ?? 'transparent';

include('../app/_parts/_header.php');

?>

<p><?= h($color); ?></p>

f:id:ryosuke-toyama:20201104144042p:plain
背景色が変更されました。

ただし、この場合result.phpにはURLにパラメーターが添えられているので背景色が適用されますが、ページ内リンクで元のページに戻るなどするとパラメーターが添えられていないので、$colorの情報は保持されません。

そこで、ブラウザにちょっとした情報を記述できるCookieの仕組みを使って背景色を保持します。

Cookieの仕組みを使い背景色情報を保持する

Cookieは簡単な情報を記述できるブラウザ側の仕組みです。
PHPではsetcookie()関数を使って設定できます。

■result.php

<?php

require('../app/functions.php');

#GETから得たcolor情報を$colorFromGetとします。
$colorFromGet = filter_input(INPUT_GET, 'color') ?? 'transparent';

#setcookie()関数で$colorFromGetをcolorという名前でCookieに保持します。
setcookie('color', $colorFromGet);

include('../app/_parts/_header.php');

?>

<p><?= h($color); ?></p>
<p><a href="index.php">Go Back</a></p>

f:id:ryosuke-toyama:20201104151257p:plain
先ほどと同じようにPinkを選択し、Go Backでindex.phpに戻ったとします。

■_header.php

<?php

#Null合体演算子を繋げて記述しています。
#colorFromGetが定義されていればその値、なければCookieの値、それもなければtransparentという記述になります。
$color = $colorFromGet ?? filter_input(INPUT_COOKIE, 'color') ?? 'transparent';

?>

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>PHP Practice</title>
</head>
<body style="background-color: <?= h($color); ?>;">

f:id:ryosuke-toyama:20201105132458p:plain これでCookieに背景色情報が保持され、元ページに戻っても反映されています。
URLにパラメーターは含まれていませんが、きちんと反映されている事がわかります。

Cookieの内容を確認する

Cookieの内容は検証ツールのApplicationパネル→Cookieから見る事ができます。
f:id:ryosuke-toyama:20201104164222p:plain

主要項目 意味
Domain このCookieが有効なドメイン
Path 有効なディレクトリ配下
Expires 有効期限(デフォルトはSession→ブラウザを閉じるまで)

また、Cookieの名前や値はダブルクリックで編集する事ができ、右クリックでDeleteとすると削除も可能です。

setcookie()関数注意点

setcookie()はHTTPプロトコルの制約によりあらゆる出力(echoやHTML)より前に使う必要があります。
また、Cookieは使える量に制限があり、かつユーザーから中身が丸見えで、上記のように編集も削除も出来てしまうためセキュリティ面の問題がある事に注意が必要です。
重要な情報はSessionという仕組みを使った方が良いですが、こちらは別記事にまとめます。

以上、どなたかの参考になれば幸いです😊

【PHP】選択形式のデータを送信する

こんにちは😊Kintarouです。

現在エンジニア転職を目指してプログラミング学習中です👨‍🎓
夢はフリーランスエンジニアになって働く人にとって働く事が楽しくなるシステムを作ること!
と、愛する妻と海外移住すること🗽

プログラミングや読んでいる本のことなど、ブログに書いていきます!
twitter : https://twitter.com/ryosuke_angry


今回参考にさせて頂いたサイト様🙇‍♂️ dotinstall.com


今回は選択形式のform部品を使った場合のデータ送信をまとめます。

select

select形式で選択した項目を送信します。
送信するパラメーターはvalue属性となります。

■index.php

#head部分などは省略します。

<form action="result.php" method="get">

#送るパラメーターをcolorという名前にしておきます。
  <select name="color">
    <option value="orange">Orange</option>
    <option value="pink">Pink</option>
    <option value="gold">Gold</option>
  </select>
  <button>SEND</button>
</form>

仮にOrangeを選択してSENDとしたとします。
f:id:ryosuke-toyama:20201102210113p:plain

■result.php

<?php

function h ($str)
{
 return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}


$color = filter_input(INPUT_GET, 'color');


#同階層にhead部分をまとめた_header.phpがあるとします。
include('_header.php');

?>


<p><?= h($color); ?></p>

f:id:ryosuke-toyama:20201102210423p:plain
value属性で指定したorangeが出力されます。

select multiple , checkbox

select形式にmultiple属性を追加するなどして、一つのname属性に複数のデータを送る場合です。
name属性を配列形式にして、受け取るfilter_input()関数にフラグをつけましょう。

■index.php

#head部分などは省略します。

<form action="result.php" method="get">

#パラメーターを複数送れるようにcolors[]配列形式にしておきます。
  <select name="colors[]" multiple>
    <option value="orange">Orange</option>
    <option value="pink">Pink</option>
    <option value="gold">Gold</option>
  </select>
  <button>SEND</button>
</form>

OrangeとPinkを複数選択してSENDとしたとします。
f:id:ryosuke-toyama:20201103224916p:plain

■result.php

<?php

function h ($str)
{
 return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}


#複数形式のデータを受け取れるように、FILTER_DEFAULT, FILTER_REQUIRE_ARRAYフラグを追加します。
$colors = filter_input(INPUT_GET, 'colors', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY);

#colors配列が空でない場合に、implode関数で配列を文字列に変換して$colorsに再代入します。
$colors = empty($colors) ? 'No Color' : implode(',', $colors);

include('_header.php');

?>


<p><?= h($colors); ?></p>

複数選択したvalueがカンマ区切りの文字列となって出力されます。
f:id:ryosuke-toyama:20201103225536p:plain

省略しますが、checkbox形式も複数選択可能で、方法は上記と同様です。

radio

ラジオボタン(radio)形式の場合です。
こちらは単数選択なのでselect形式で一緒ですが、未選択の場合はNullが入るのでそこの処理を紹介します。

■index.php

#head部分などは省略します。
<form action="result.php" method="get">
  
    #単数colorに戻してラジオボタンを作成します。
    <label><input type="radio" name="color" value="orange">Orange</label>
    <label><input type="radio" name="color" value="pink">Pink</label>
    <label><input type="radio" name="color" value="gold">Gold</label>
  <button>Send</botton>
</form>

ラジオボタンでOrangeを選択してSENDします。
f:id:ryosuke-toyama:20201104115921p:plain

■result.php

<?php

function h ($str)
{
 return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}

$color = filter_input(INPUT_GET, 'color');

#isset()関数でNullでないかどうかの真偽値を三項演算子で分岐させます。
$color = isset($color) ? $color : 'No Color';

include('../app/_parts/_header.php');

?>

<p><?= h($color); ?></p>

orangeが出力されます。
f:id:ryosuke-toyama:20201104120145p:plain

Null合体演算子

isset()関数を用いた上記の例ですが、Null合体演算子を用いて簡単に記述する事も出来ます。

例) isset()を用いた三項演算子

$color = isset($color) ? $color : 'No Color';

例) Null合体演算子

$color = $color ?? 'No Color';

式が短いのでfilter_inputの行と同じ行に記載した場合を書いておきます。

$color = filter_input(INPUT_GET, 'color') ?? 'No Color';

GETで送られたcolorという名前のパラメーターを変数$colorに代入。Nullの場合は'No Color'を代入。という式になります。

以上、どなたかの参考になれば幸いです😊

【PHP】別ファイルへのデータ送信

こんにちは😊Kintarouです。

現在エンジニア転職を目指してプログラミング学習中です👨‍🎓
夢はフリーランスエンジニアになって働く人にとって働く事が楽しくなるシステムを作ること!
と、愛する妻と海外移住すること🗽

プログラミングや読んでいる本のことなど、ブログに書いていきます!
twitter : https://twitter.com/ryosuke_angry


今回参考にさせて頂いたサイト様🙇‍♂️ dotinstall.com


別のファイルにデータを送信する

inputで入力したデータを別のファイルに送信する方法についてまとめます。
まずはform部品を作ります。

■index.php

#head部分などは省略します。

#form内のパラメーターを同階層内に作成したresult.phpファイルにGETメソッドで送ります。
<form action="result.php" method="get">

#送るパラメーターをmessageという名前にしておきます。
  <input type="text" name="message">
  <button>SEND</button>
</form>

仮にinput部分に「赤」と入力したとします。
f:id:ryosuke-toyama:20201102200304p:plain

■result.php

<?php

function h ($str)
{
 return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}


#GETメソッドで送られたmessageというパラメータが$messageだよ。という記述です。
#trimはもし「赤」の前後に空白があった場合に無視するためにつけています。
$message = trim(filter_input(INPUT_GET, 'message'));

#パラメータが空の場合はNo colorとします。
$message = $message !== '' ? $message : 'No color';

#同階層にhead部分をまとめた_header.phpがあるとします。
include('_header.php');

?>


<p><?= h($message); ?></p>

「赤」の記述がクエリパラメーターでresult.phpに送られ、resut.phpに反映されている事がわかります。
f:id:ryosuke-toyama:20201102201607p:plain

改行のある文章を送信する

次に改行のある文章の送信方法です。
textareaを使いますが、上記のままだと改行を入れてもHTMLでは改行を改行として処理してくれません。
改行をbrタグで表記する必要があります。
nl2br関数を使います。(new lline to br)

■index.php

#head部分などは省略します。

<form action="result.php" method="get">

  <textarea name="message"></textarea>
  <button>SEND</button>
</form>

■result.php

<?php

function h ($str)
{
 return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}

$message = trim(filter_input(INPUT_GET, 'message'));
$message = $message !== '' ? $message : 'No color';

include('_header.php');

?>

#nl2brとする事で、textareaに改行があったら改行として出力してくれます。
<p><?= nl2br(h($message)); ?></p>

以上、どなたかの参考になれば幸いです😊

【PHP】ブロックを伴う関数のわかりやすい記法

こんにちは😊Kintarouです。

現在エンジニア転職を目指してプログラミング学習中です👨‍🎓
夢はフリーランスエンジニアになって働く人にとって働く事が楽しくなるシステムを作ること!
と、愛する妻と海外移住すること🗽

プログラミングや読んでいる本のことなど、ブログに書いていきます!
twitter : https://twitter.com/ryosuke_angry


今回参考にさせて頂いたサイト様🙇‍♂️ dotinstall.com


今回はifやforeach等、ブロックを伴う関数が入れ子になった場合にわかりやすく記述する為の記法についてまとめます!

ブロックを伴う関数をネストする

ifやforeachなどのブロックを伴う関数をネストして使う場合、構造終了のタグがどの関数のものかわかりにくくなる事が多々あるかと思います。
PHPの場合わかりやすく表記する方法があるようなのでそちらをまとめてみます。

<?php
#このphpタグの中は今回の本題ではないので気にしなくて大丈夫です。

function h ($str)
{
  return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}

$name = [
  'Kintarou',
  'Kinjirou',
  'Kinsabrou',
];

?>

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>PHP Practice</title>
</head>
<body>
  <ul>

  <!-- 本題はこちらから
    まず$names変数が空配列かどうかをif文で分岐させています。 -->

    <?php if (empty($names)) { ?>
      <li>Hello, Nobody !</li>
    <?php }else{ ?>

  <!-- 空配列でない場合、配列の要素毎に「Hello, 〜〜 !」という文を出力します。 -->

      <?php foreach ($names as $name) { ?>
        <li>Hello, <?= h($name); ?> !</li>
      <?php } ?>
    <?php } ?>

  <!-- foreachとifの構造終了タグ"}"が連続して記述されます。 -->

</ul>
</body>
</html>

○出力ページ
f:id:ryosuke-toyama:20201102160155p:plain

今回のような場合は1度のネストなのであまり気にならないかもしれませんが、これがいくつか重なってくると何の閉じタグなのかをいちいち気にする必要があります。

そこで、ブロックの記法を以下のように書き換えられます。

例)foreachの場合

foreach ( $names as $name ) {

}

foreach ( $names as $name ) :

endforeach;

これで何の閉じタグを表しているのかがすぐにわかります。
先ほどの例の場合は以下のようになります。

<?php
#このphpタグの中は今回の本題ではないので気にしなくて大丈夫です。

function h ($str)
{
  return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}

$name = [
  'Kintarou',
  'Kinjirou',
  'Kinsabrou',
];

?>

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>PHP Practice</title>
</head>
<body>
    <ul>
    <!-- 本題はこちらから
    まず$names変数が空配列かどうかをif文で分岐させています。 -->
    <?php if (empty($names)) : ?>
      <li>Hello, Nobody !</li>
    <?php else: ?>
      
    <!-- 空配列でない場合、配列の要素毎に「Hello, 〜〜 !」という文を出力します。 -->

      <?php foreach ($names as $name) : ?>
        <li>Hello, <?= h($name); ?> !</li>
      <?php endforeach; ?>
    <?php endif; ?>

<!-- どちらの構造終了タグかが一目でわかります。 -->

</ul>
</body>
</html>

この記法は、for文(endfor;)やwhile文(endwhile;)、switch文(endswitch;)にも有効です。
ただ、do-while文には使えないので注意が必要です。

以上、どなたかの参考になれば幸いです😊

【PHP】特殊文字をエスケープする

こんにちは😊Kintarouです。

現在エンジニア転職を目指してプログラミング学習中です👨‍🎓
夢はフリーランスエンジニアになって働く人にとって働く事が楽しくなるシステムを作ること!
と、愛する妻と海外移住すること🗽

プログラミングや読んでいる本のことなど、ブログに書いていきます!
twitter : https://twitter.com/ryosuke_angry


今回参考にさせて頂いたサイト様🙇‍♂️ dotinstall.com


特殊文字エスケープする

今回はPHP特殊文字エスケープするための関数 htmlspecialcharsをまとめます。

仮にPHPで出力する文字列の中に <script>タグが含まれていると、それは文字ではなくコードとして読み込まれてしまい、悪意のあるコードを第3者に書き込まれる等悪用される可能性があります。

■危険なコードの例

<?php

#アラートを表示するscriptタグを記述します。
$message = '<script>alert("Passwordを送信します");</script>';

?>

<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>危険なページ</title>
</head>
<body>
  <h1>ここにPHPコードを記述します</h1>
  <p><?= $message; ?></p>
</body>
</html>

このファイルを実行すると以下のアラートが表示されます。
f:id:ryosuke-toyama:20201031190653p:plain

今回はただアラートを表示するだけですが、もし何かしらのデータを送信するなどのコードが記述されると大変危険です。

<script>タグをコードとして認識させないためにhtmlspecialcharsを使います。

エスケープしたコードの例

<?php

$message = '<script>alert("Passwordを送信します");</script>';

?>

<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>危険なページ</title>
</head>
<body>
  <h1>ここにPHPコードを記述します</h1>

  <!-- htmlspecialcharsでエスケープされてるので文字列として出力されます -->
  <!-- ENT_QUOTESは、クォーテーションマークも文字列として認識させるためのフラグです -->

  <p><?= htmlspecialchars($message, ENT_QUOTES, 'UTF-8'); ?></p>
</body>
</html>

このようにすると出力は以下のようになります。

f:id:ryosuke-toyama:20201031193223p:plain

無事エスケープ出来ました!

以上、どなたかの参考になれば幸いです😊

【PHP】例外処理

こんにちは😊Kintarouです。

現在エンジニア転職を目指してプログラミング学習中です👨‍🎓
夢はフリーランスエンジニアになって働く人にとって働く事が楽しくなるシステムを作ること!
と、愛する妻と海外移住すること🗽

プログラミングや読んでいる本のことなど、ブログに書いていきます!
twitter : https://twitter.com/ryosuke_angry


今回参考にさせて頂いたサイト様🙇‍♂️ dotinstall.com


例外処理を記述する

例外(ユーザーの想定していない動作)が発生した場合の記述方法です。
例外の発生しそうな箇所をtry{ ... } catchで囲み、例外の条件をthrow new Exceptionで返します。
例外が発生した場合の動作はcatch以降に記述します。

■User.php

<?php

class User
{
  private $name;

  #Userがnewされた際の引数$nameが13文字以上だった場合にExceptionクラスのインスタンスを生成する。
  public function __construct($name)
  {
    if (strlen($name) > 12) {
      throw new Exception("ユーザー名は12文字以内で登録して下さい");
    }

    $this->name = $name;
  }

  public function profile()
  {
    printf('%s' . PHP_EOL, $this->name);
  }
}

■main.php

<?php

spl_autoload_register(function ($class){
  require($class . '.php');
});

#Userクラスをnewする記述をtry{ ...} catchで囲む。
try {
  $users = [];
  $users[0] = new User('Mr.Kintaroooou');
  $users[1] = new User('Kinjirou');

  foreach($users as $user) {
    $user->profile();
  }
} catch (Exception $e) {
  echo $e->getMessage() . PHP_EOL;
}

#=>ユーザー名は12文字以内で登録して下さい

#$users[0]のインスタンス生成の際、引数が12より大きい字数の為、catch以降の処理がされている。
#ExceptionのインスタンスのgetMessageメソッドにより生成された時の引数(エラーメッセージ)が出力されている。

Exceptionが生成されて以降の処理($users[1]の生成以降)も処理は止まっている事に注意です。

以上、どなたかの参考になれば幸いです😊

【PHP】外部ファイルの読み込み

こんにちは😊Kintarouです。

現在エンジニア転職を目指してプログラミング学習中です👨‍🎓
夢はフリーランスエンジニアになって働く人にとって働く事が楽しくなるシステムを作ること!
と、愛する妻と海外移住すること🗽

プログラミングや読んでいる本のことなど、ブログに書いていきます!
twitter : https://twitter.com/ryosuke_angry


今回参考にさせて頂いたサイト様🙇‍♂️ dotinstall.com


外部ファイルを読み込む

外部のファイルを読み込む方法です。
純粋に外部ファイルを使いたい時や、コードが長くなってファイルを分割したい場合に使えます。

記述 処理
require 外部ファイルを読み込む。読み込めなかった場合処理が止まる。
include 外部ファイルを読み込む。読み込めなかった場合も処理は止まらない。
require_once requireと同じだが、既に読み込まれていたらスキップする。
include_once includeと同じだが、既に読み込まれていたらスキップする。

仮にUserクラスの記述を読み込んで、別ファイルとしてメソッドを使ってみます。
User.phpファイルとmain.phpファイルに分けますが、2つのファイルは同階層上にあるとします。

■User.php (Userクラスの定義のみ記述)

<?php

class User
{
  private $name;

  public function __construct($name)
  {
    $this->name = $name;
  }

  public function profile()
  {
    printf('%s' . PHP_EOL, $this->name);
  }
}

■main.php (実行するコードを記述)

<?php

#requireでUser.phpファイルを呼び出しています。
require('User.php');

$users = [];
$users[0] = new User('Kintarou');
$users[1] = new User('Kinjirou');


#User.php上のメソッドが問題なく読み込まれています。
foreach($users as $user) {
  $user->profile();
}

#=>Kintarou
#=>Kinjirou

外部ファイルを自動で読み込む

クラスをファイル毎に分けたは良いものの、いちいちクラス毎にrequireするのは面倒となった場合にspl_autoload_register(spl => standard php library)という関数が使えます。

先ほどの例のmain.phpのみ変更します。

■main.php

<?php

#この記述により、クラスがnewされた時にrequireされていなければ、newされたクラス名を$classに代入してクラス名.phpファイルを読み込む。
spl_autoload_register(function ($class){
  require($class . '.php');
});

$users = [];
$users[0] = new User('Kintarou');
$users[1] = new User('Kinjirou');

foreach($users as $user) {
  $user->profile();
}

#=>Kintarou
#=>Kinjirou

以上、どなたかの参考になれば幸いです😊