PHP
$a <=> $b
$a < $b
の場合は-1 ,$a == $b
の場合は0,$a > $b
の場合は1を返す
JSでいうオブジェクトもPHPでは配列として書く。
$names = [
"sato"=>"佐藤",
"suzuki"=>"鈴木",
"takahashi"=>"高橋",
]
echo $names["sato"] //佐藤
JSでいうforEachもPHPにはある。
$names = [
"sato" => "佐藤",
"suzuki" => "鈴木",
"takahashi" => "高橋",
];
foreach ($names as $key => $value) {
echo $key . $value . "<br/>";
}
//連想配列の場合(`$key`,`$value`はなんでも良い )
//foreach(<配列名> as $key => $value )
//普通の配列の場合
//foreach(<配列名> as $value )
外部ファイルの読み込みは4種類ある。JSのように外部ファイルで読み込みたい場合にexport
をする必要はない。
include "./data.php";
require "./data.php";
include_once "./data.php";
require_once "./data.php";
- include : 指定されたファイルが読み込めない場合でも処理を継続する(アラートが出る)
- require : 指定されたファイルが読み込めない場合は処理を注視する(エラーになる)
- include_once : すでに同じファイルが読み込まれている場合はincludeを実行しない
- require_once : すでに同じファイルが読み込まれている場合はrequireを実行しない
関数の引数と返り値の型宣言。TSと違って型を宣言したところでVS Codeがアラートを出してくれるわけでもない。返り値の肩の宣言は:float
のようにして書く。
<?php
function tax(int $price): float
{
return $price * 1.1;
}
ファイルを開く
$fp = fopen(<読み込みたいファイルのパス>, <読み込みモード>);
<読み込みモード>:r
(読み取り専用),w
(書き出し専用)などいろいろある。
書き出しはどうやって行うのか?
CSVの読み込みにはfgetcsv
を用いる。
$fp = fopen("./bookdata.csv", "r");
$row = fgetcsv($fp);
var_dump($row) //「PHPの本,9994295001249,980,2021-5-1,佐藤」のようなものが流れる。
これでCSVの一行目が読み込まれる。ではCSVを一行ずつ読み取るにはwhile文を使う。
while($row = fgetcsv($fp)){
var_dump($row)
}
なぜこれで全ての行が出力されるのかというとfgetcsv
を1回実行すると次の行が読み込まれて$row
に代入されるから。全ての行を読み取った後は$row=false
となりループから抜ける。
while文は嫌いなのでfor文でなんとか書いてみようと思った。
sizeof()
でファイルの行数が取れるとのこと(参考:http://phprecord.blog81.fc2.com/blog-entry-23.html)
$rowNum = sizeof(file("./bookdata.csv"));
for ($i = 0; $i < $rowNum; $i++) {
$row = fgetcsv($fp);
echo $row[0];
echo "<br/><br/>";
}
<form action="sample.php" method="post">
<input type="text" name="a" />
<input type="submit" value="送信する" />
</form>
テキストボックスで入力されたものを受け取るにはsample.phpで
<?php
echo $_POST["a"];
とする。
XSS対策のための関数htmlspecialchars()
関数
htmlspecialchars(<変換する文字列>,<フラグ>,<エンコーディング(UTF-8とか)>)
<フラグ>はENT_QUOTES
が多いっぽい。このフラグをつけておくとシングルクォートもダブルクォートもエスケープする。
のようにキャストできる。$_POST["height"];
が文字列の場合は0
になる。
$height = (float)$_POST["height"];
PHPでJSONを扱う。
<?php
$url = "https://zipcloud.ibsnet.co.jp/api/search?zipcode=6711146";
$res = file_get_contents($url);
var_dump($res);
POSTで通信する方法(https://qiita.com/suisuina/items/9b7d44118266f97a577d)
ブラウザのディベロッパーツールのネットワークから見るとGETmethodになってる〜。XAMPPからブラウザはGETmethodで通信が行われて、XAMPPからJSON PlaceholderへはPOSTで行っとるってことなんやろか??
POSTで行えてるかどうかの確認手段はないんか。
$urlJson = 'https://jsonplaceholder.typicode.com/posts';
// 送信データ
$data = array(
"title" => "foo",
"body" => "bar",
"userId" => 1,
);
$data = http_build_query($data, "", "&");
$header = array(
"Content-Type: application/x-www-form-urlencoded",
"Content-Length: " . strlen($data)
);
$options = array(
'http' => array(
'method' => 'POST',
'header' => implode("\r\n", $header),
'content' => $data
)
);
$contents = file_get_contents($urlJson, false, stream_context_create($options));
var_dump($contents);
curl
を使う方が速いらしい。
API通信で受け取ったレスポンスをPHPが扱える形にする。
$res = file_get_contents($url);
のままだとレスポンスがstringのままなので$res = json_decode($res, true);
として配列にする。
<?php
$url = "https://zipcloud.ibsnet.co.jp/api/search?zipcode=" . (int) $_GET["zip"];
echo $_GET["zip"] . "<br/>";
$res = file_get_contents($url);
$res = json_decode($res, true);
var_dump($res);
正規表現
preg_match
もpreg_match_all
もマッチした文字列の数を返す。(preg_match
は最初に見つかるとそれで検索を打ち切るから0or1しか返さない。)
preg_match(<正規表現>,<検索文字列>,<マッチした文字を格納する配列>)
$str = "〒101-0051東京都千代田区神田神保町1-105";
preg_match("/\d{3}-\d{4}/u", $str, $match);
var_dump($match); // ["101-0051"]
繰り返しマッチをしたい場合はpreg_match_all
とする。/g
とかは無理。
$str = "〒101-0051東京都千代田区神田神保町1-105-0009";
preg_match_all("/\d{3}-\d{4}/u", $str, $match02);
var_dump($match02); // [101-0051,105-0009]
nullでないかどうかを確かめる
$a = 123
isset($a) //true
isset($b) //false $bは未定義なのでfalseになる
DBに接続する
$opt = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,//SQLでエラーを吐いたときは全て例外処理をする
PDO::ATTR_EMULATE_PREPARES => false,
PDO::MYSQL_ATTR_MULTI_STATEMENTS => false,
];
//data base handler の略
$dbh = new PDO("mysql:samplehost=host;dbname=sampledbname", $user, $password, $opt);
// samplehostやsampledbnameは自分で決める
SQLを実行して取得結果を表示する。csvの中身をwhile文で表示したことと同じようなことを行う。
while ($row = fgetcsv($fp)) {}
new PDO
↓
PDO -> query(SQL)
↓
PDOStatement -> fetch()//これをループで回す
プリペアードステートメント:fefefe
としてあとで値を代入する。
$dbh = new PDO
$sql = "INSERT INTO books (id,title,isbn,price,publish,author) VALUES (NULL,:title,:isbn,:price,:publish,:author)";
$stmt = $dbh->prepare($sql); //PDOStatement
代入方法
PDOStatementオブジェクト->bindParam(<":プレースホルダ名(fefefeとか)">,<置き換える値>,<データ型>);
ここの<データ型>は
PDO::PARAM_BOOL //論理型
PDO::PARAM_NULL //Null型
PDO::PARAM_INT //intl型
PDO::PARAM_STR //文字列はこれ
SQL実行
//プレースホルダに代入
$stmt->bindParam(":author", $_POST["author"], PDO::PARAM_STR);
//SQL実行
$stmt->execute();
PHPでのバリデーション
制御構文:https://www.miki-ie.com/php/remove-escape-php-control-characters/
[:cntrl:]//制御構文(改行など)
[^:cntrl:]//制御構文以外(全ての文字)
\A //開始
\z //終了
JSでいうsplitメソッド(配列を返す)
<対象文字列>.split(<区切り文字列>)
同じく配列を返す。
explode(<区切り文字列>,<対象文字列>)
日付が正しいか確かめる関数。閏年も考慮される。(true/false)を返す
checkdate(<月の数値>,<日の数値>,<年の数値>)
echoのショートタグ
<?php echo $aaa ?>と
<?= $aaa ?>は同じ
include __DIR__ . "/inc/functions.php"
としておくと全体が絶対パスになるように__DIR__
が補完してくれる。