変数のスコープ(=有効範囲)

 

 

 

今回のお題は

変数のスコープ、有効範囲についてです。

 

 

\登場人物はー?/

・ローカル変数

・グローバル変数

・静的(static)変数

 

コメントつけまくったらすんごーい醜いww

 

コミットコメント

 

▶️ローカル変数

関数内で定義されて、有効範囲はその関数内のみ。

4行目の$aはローカル変数ではない。

  4 $a = 1;
  5 function showLocalNum()
  6 {
  7   //-----ローカル変数 $aのスコープ ここから-----
  8   $a = 2; // ←ローカル変数 $aの定義
  9   print 'ローカル変数 $a: ' . $a . "\n";
 10   //-----ローカル変数 $aのスコープ ここまで-----
 11 }
 12 showLocalNum(); // 2 →ローカル変数 $a
 13 print '4行目の$a: ' . $a . "\n"; //8行目のローカル変数の$aではない。

 

ローカル変数 $a: 2
4行目の$a: 1

 

▶️グローバル変数

関数内外問わず定義され、有効範囲はPHPスクリプト全体

 17 $g = 1;
 18 function showGlobalNum()
 19 {
 20   global $g;
 21   $g++;
 22   print 'グローバル変数 $g: ' . $g . "\n";
 23 }
 24 print '関数showGlobalNum実行前の17行目の$g: ' . $g . "\n"; // 1 まだグローバル変数になってない。
 25 showGlobalNum(); // 2 →グローバル変数 $g
 26 showGlobalNum(); // 3 →グローバル変数 $g
 27 print '関数showGlobalNum実行前後の17行目の$g: ' . $g . "\n"; // 3 グローバル変数 $gになってる

 

関数showGlobalNum実行前の17行目の$g: 1
グローバル変数 $g: 2
グローバル変数 $g: 3
関数showGlobalNum実行前後の17行目の$g: 3

 

▶️静的(static)変数

関数内で定義される。初期化は最初の一回のみ行われ、その後は前の値が残る。

 31 //static $d = 100; //関数外では定義できない
 32 function showStaticNum()
 33 {
 34   static $s = 100; //←ローカル変数 $sの定義
 35   $s++;
 36   print '静的(static)変数 $s: ' . $s . "\n";
 37 }
 38 showStaticNum(); // 101
 39 showStaticNum(); // 102
 40 showStaticNum(); // 103

 

静的(static)変数 $s: 101
静的(static)変数 $s: 102
静的(static)変数 $s: 103

 

 

<まとめ>

ローカル変数しか、あんまり使わんけども。

 

 

requireとincludeの違い

 

\ 今回の主人公はー?こちらっ /

・require

・require_once

・include

・include_once

 

 

そもそも上の四つは外部ファイルを参照するときに使います。

requireとincludeの違い

require と include はほぼ同じだが、失敗した場合の動きが異なる。

require → 致命的なエラーを発生する。スクリプトの処理がそこで止まってしまう。 include → 警告 (E_WARNING) を発するが、スクリプトの処理は続行する。

 

<イメージ>

require …

「君が必要なんだ!だから、君がいないならもうやめてしまおう、

こんなこと。」てきな

 

include…

「お前もくる?あ、どっちでもいいよ?無理なら全然いいから〜、

お前おらんでもできるから。」

てきな。

 

※あくまでも個人的なイメージです。

 

 

 

では、require と include を比べて見ましょう。

こんなファイルを用意。requireVsInclude.php

  1 <?php
  2
  3 /**
  4  * 今回比較するもの
  5  * - require
  6  * - include
  7  */
  8
  9 //わざと失敗させる:該当ファイル(notFound.php)がない
 10 echo "---include(Error) START---\n";
 11 include(dirname(__FILE__) . '/notFound.php');
 12 echo "---include(Error) E N D---\n\n";
 13
 14 echo "---include START---\n";
 15 include(dirname(__FILE__) . '/dummy/include.php');
 16 echo "---include E N D---\n\n";
 17
 18 //わざと失敗させる:該当ファイル(notFound.php)がない
 19 echo "---require(Error) START---\n";
 20 require(dirname(__FILE__) . '/notFound.php');
 21 echo "---require(Error) E N D---\n\n";
 22
 23 echo "---require START---\n";
 24 require(dirname(__FILE__) . '/dummy/require.php');
 25 echo "---require E N D---\n\n";

 

いざ、実行!

$ php requireVsInclude.php
---include(Error) START---

Warning: include(/xxxxxx/php/src/notFound.php): failed to open stream: No such file or directory in/xxxxxx/php/src/requireVsInclude.php on line 11

Warning: include(): Failed opening '/xxxxxx/php/src/notFound.php' for inclusion (include_path='.:') in/xxxxxx/php/src/requireVsInclude.php on line 11
---include(Error) E N D---

---include START---
includeしました。
---include E N D---

---require(Error) START---

Warning: require(/xxxxxx/php/src/notFound.php): failed to open stream: No such file or directory in/xxxxxx/php/src/requireVsInclude.php on line 20

Fatal error: require(): Failed opening required '/xxxxxx/php/src/notFound.php' (include_path='.:') in/xxxxxx/php/src/requireVsInclude.php on line 20

 

11行目のincludeで存在しないファイルですとWarningされますが、

処理は続けていますね。

そして、次のinclude処理(15行目)は正しく行われています。

一方で、20行目のrequireは「存在しないファイルをopenできなかった」

とFatalErrorしています。

よって、ここ(20行目)で処理が中止され24行目のrequire処理は実行されませんでした。

 

 

つづいて….  require_onceとinclude_onceを比較します。

こんなファイルを用意。once.php

  1 <?php
  2
  3 /**
  4  * 今回比較するもの
  5  * - require_once
  6  * - include_once
  7  */
  8
  9 //~_onceつかってみる
 10 echo "---require START---\n";
 11 require(dirname(__FILE__) . '/dummy/require.php');
 12 echo "---require E N D---\n\n";
 13
 14 echo "---require_once START---\n";
 15 require_once(dirname(__FILE__) . '/dummy/require.php');
 16 echo "---require_once E N D---\n\n";
 17
 18
 19 echo "---include START---\n";
 20 include(dirname(__FILE__) . '/dummy/include.php');
 21 echo "---include E N D---\n\n";
 22
 23 echo "---include_once START---\n";
 24 include_once(dirname(__FILE__) . '/dummy/include.php');
 25 echo "---include_once E N D---\n\n";

 

いざ、出 陣!

ちなみに

/dummy/require.php がよばれると「requireしました。」をechoします。

/dummy/include.php がよばれると「includeしました。」をechoします。

$ php once.php
---require START---
requireしました。
---require E N D---

---require_once START---
---require_once E N D---

---include START---
includeしました。
---include E N D---

---include_once START---
---include_once E N D---

11行目で一度requireされたので、15行目のrequire_onceでは呼び出されませんでした。

includeでも同様で、

20行目で一度includeされたので、24行目のinclude_onceでは呼び出されませんでした。

 

 

\ まとめ /

・絶対必要なファイルはrequireでよぶ。

何回呼んじゃうか、わからん時はrequrie_once使っとこう。

 

参照(リファレンス)渡しは、ニコイチになる呪文

久々にPHPネタを書きます。

といっても参照渡しって他の言語でもあるかと思いますが、、、長い目でみてください。

▶︎参照(リファレンス)渡しとは

引数の渡し方の一つ。
引数の渡し方では、「参照渡し」以外に、
ごく一般的でよく見る普通の引数の渡し方に「値渡し」がある。

 

まず、ごく一般的でよく見る普通の引数の渡し方の

「値渡し」を見ていきます。

/**
 * 数値型を文字列型に変更する
 *
 * @param integer $number
 * @return string $number
 */
function convertString($number)
{
  //return (string)$number;のが冗長ではないが、そこは我慢。
  $number = (string)$number;
  return $number;
}

$a = 1;
convertString($a); 
var_dump($a); //int(1) 返り値を$aに格納していないため、$a = 1のまま

$b = 2;
$b = convertString($b);
var_dump($b); //string(1) "2"

 

 

その後に、「参照渡し」を見てみる。

//PHP5.4.0から仕様変わったやーつー。※今回はPHP5.5を想定
/**
 * 数値型を文字列型に変更する
 *
 * @param integer $number
 * @return string $number
 */
function convertString_reference(&$number)
{
  $number = (string)$number;
  return $number;
}

$c = 3;
//PHP5.4.0以前ではconvertString_reference(&$c)でも呼べる
convertString_reference($c); //$numberと$cがニコイチとなる。
var_dump($c); //string(1) "3"

$d = 4;
//$numberと$dがニコイチ(同等)となる。
$d = convertString_reference($d); 
var_dump($d); //string(1) "4"

参照渡しをすると、ニコイチになれる!

ニコイチってもう古いんかな?昔はやってたからいい例えと思って使ってみたw

参照渡しで渡された引数は、関数内のローカル変数と同等になる。

片方が+1されると、他方も+1される、まさしくニコイチ!

 

 

影響範囲を考えないと使いにくそうで、自から使ったことはまだないですが、

使えるいいタイミング見つけてみたいと思います。

awkコマンド良き。

\ 全体コードはこちら /
https://gist.github.com/kin29/18349f0aec11df73325ab466f8621232
 

awkって「オーク」と読むみたいです。
awkって訳すと、

  • 不自然な
  • ぎこちない

とかって意味らしいですが、これには全く関係なく、

    開発者3人の名前(Aho、Weinberger、Kernighan)の頭文字から命名された。

らしいです。

 

▶︎awkコマンドとは?

テキストデータの加工や処理などができる。

 

▶︎使い方

パイプ「|」で使うことが多いです。
パイプは、出力結果をパイプ後のコマンドに渡すことができるヤーツーでしたね。

# 1が表示される
# awkコマンドによってprintが実行される
echo 1 2 | awk '{print $1}'

 

計算ができる

# 3(=1+2)が表示される 
echo 1 2 | awk '{print $1+$2}'

 

「;(セミコロン)」で複数処理できる

# 3(=1+2)が表示される 
echo 1 2 | awk '{x=$1+$2; print x}'

 

seqコマンドと組み合わせる

seq 1 10 | awk '{x=$1+100; print x}'
101
102
103
104
105
106
107
108
109
110

出力する条件を決めれる。

# 3(=1+2)が表示される 
echo 1 2 | awk '$1{print}' 

 

ファイル(dummy/awk.txt)の出力結果を加工する
dummy/awk.txt

1 2
3 4

→ awk.txtはファイルなので「|」はいらない

# awk '{print $1 * $2;}' dummy/awk.txtと同じ
$ awk '{print $1 + $2;}' < awk.txt
3
7

seqを使ってワンライナー書くよ。

ワンライナーって短い命令文なのに、いっぱい仕事してくれてスマート^^

全体コードはこちら!
https://gist.github.com/kin29/8950d25cab8bd877efff88764515cf66

 

▶︎シェル変数

x=3
echo $x  #echo xではない。

出力結果

3

 

 

# コマンドを変数に入れたい時は「`」で囲む
d=`date`
echo $d

出力結果

2018年 1月 5日 金曜日 22時42分54秒 JST

 

▶︎seqコマンド

# 初期値1,間隔1(デフォルト),最大値10

$ seq 1 10
1
2
3
4
5
6
7
8
9
10

 

# 初期値1,間隔2,最大値5

$ seq 1 2 5
1
3
5

 

▶︎ forループ

$ for a in 1 2 3; do echo $a; done
1
2
3

$a に 1 を代入 → echo $a(=1)
$a に 2 を代入 → echo $a(=2)
$a に 3 を代入 → echo $a(=3)

↑と同じ結果となる

# seq 1 3は文字じゃなくてコマンドなので「`」で囲む
for b in `seq 1 3`; do echo $b; done

 

 

もっといろんなコマンド知りたい!!!
次はawkコマンドとかを探求したいと思います。

標準入出力、リダイレクト、パイプ

実家からお歳暮でもらったであろうビールをかっさらってきて、

帰宅と同時に飲むのが至福のひとときな今日この頃。

 

 

全体はこんな感じです。

 

▶︎標準入出力とは。

lsやcatなどの実行結果は、
指定しない限り、普通は画面に表示される。←これです!
デフォルトではそれぞれ以下のようになっている。
標準入力 → キーボード
標準出力 → 画面

こんな感じ

# キーボードで入力(標準入力)したものがそのままに出力(標準出力)される
echo hello!

 

▶︎リダイレクトとは。

「リダイレクト」を使うと、標準入出力を指定のファイルに変更することができる。

出力リダイレクト

画面(標準出力)でなく、ファイルに結果を出力する

# 「hello!」という出力結果を新規ファイルoutput.txtに出力
echo hello! > output.txt

#「>」は上書き
# dateコマンドの出力結果を既存ファイルoutput.txtに上書き
date > output.txt

#「>>」は追記
# 「add!」という出力結果を既存ファイルoutput.txtに追記
echo add! >> output.txt

入力リダイレクト

キーボード(標準入力)でなく、ファイルからの入力をコマンドに渡す

# cat output.txtと同じ結果
# cat 0< output.txtと同じ結果
cat < output.txt

echo 6+1 > input.txt
# bc 0< input.txtと同じ結果
bc < input.txt

 

▶︎パイプ「|」とは。

標準出力をコマンドに渡す

# 中間ファイルが不要となる 
# echo 6+1 > input.txt && bc < input.txt と同じ結果
echo 6+1 | bc

 

#余談

過去のコミット全部自分のものにしたい時

$ git filter-branch -f --env-filter "GIT_AUTHOR_NAME='名前';\
 GIT_AUTHOR_EMAIL='メールアドレス';\
 GIT_COMMITTER_NAME='名前';\
 GIT_COMMITTER_EMAIL='メールアドレス';" \
HEAD

過去のコミットを編集することは歴史をガラリとかえて未来に影響が大きいのであまりしないほうがいいです、はい。
けど今回グローバルネームでコミットしてしまっていたため変更しました。もちろん

$ git config --local user.name 名前
$ git config --local user.email "メールアドレス"

もしましたよ。

SQLの色々

寒いですね。なんかすんごく太りました (x_x)

SQLの本で「なるほど」ってなったことを書きます。

 

■SERIAL型 …連番をふることができる。(postgreSQL)

CREATE TABLE test_db(
  id smaillint,
  name text
);
INSERT INTOtest_db VALUES(1,'ガズ');
INSERT INTO test_db VALUES(2,'シャーロット');
INSERT INTO test_db VALUES(3,'マーニー');

今時点では
id   |     name     |
——–+————–+-
1      | ガズ         |
2      | シャーロット |
3      | マーニー     |

 

そこに、SERIAL型のカラムnumberを追加する。

ALTER TABLE test_db ADD COLUMN number serial;

id   |     name     | number
——–+————–+——–+—–
1      | ガズ         |      1 |
2      | シャーロット|      2 |
3      | マーニー     |      3|

勝手に連番ふってくれる!!!

CREATE SEQUENCEをしなくても、シーケンスをつくってくれます。

 

カラムnumberを指定しなくても連番を勝手にいれてくれる!

INSERT INTO test_db VALUES(4,'アーロン');

id   |     name     | number
——–+————–+——–+—–
1      | ガズ         |      1 |
2      | シャーロット|      2 |
3      | マーニー     |      3|
4      | アーロン     |      4|

 

■複数の論理演算子の優先度

(1) NOT

(2) AND

(3) OR

 

■ JOIN の色々

▶︎INNER JOIN(内部結合)

書き方: JOIN テーブル名

片方にしか存在しない行は結合されない

 

▶︎OUTER JOIN(外部結合)

・FULL OUTER JOIN

書き方: FULL (OUTER) JOIN テーブル名

片方にしか存在しない行でも他方をNULLにして結合する

 

・LEFT OUTER JOIN

書き方:LEFT (OUTER) JOIN テーブル名

左テーブルにしか存在しない行は右テーブルをNULLにして結合する。

右テーブルにしか存在しない行は結合されない。

 

・RIGHT OUTER JOIN

書き方:RIGHT (OUTER) JOIN テーブル名

右テーブルにしか存在しない行は左テーブルをNULLにして結合する。

左テーブルにしか存在しない行は結合されない。

 

■集合関数におけるNULLの扱い

SUM/MAX/MIN/AVG … NULLは無視

→NULLを0に置き換えて集計したい時は、COALESCE関数を使うといい。

 

COUNT … カラム名指定の場合、NULLはカウントしない。

しかし、「*」の時はNULLを含めてカウントする。

→count(カラム名)とcount(*)で結果が異なることがある。

 

 

 

■SQLの区分

・DML …Data Manipulation Language – データ操作言語

SELECT / INSERT / UPDATE / DELETE など

 

・DDL …Data Definition language – データ定義言語

データベース、テーブル、ビューなどの基本データを定義・作成するための言語。

CREATE / ALTER / DROP など

インデックスやシーケンスを含む。データベールオブジェクトと言うこともある。

 

・DCL …Data Control Language – データ制御言語

データベースのユーザー権限の管理やデータのトランザクション処理を行う為の言語

GRANT / REVOKE / BEGIN / COMMIT / ROLLBACK など

 

■トランザクション

…複数の指示をひとかたまりのSQL文として扱うこと。

「一方のテーブルでは差し引き、他方のテーブルでは差し引いた分足す」

といった指示間を他の人に邪魔されると一貫性がなくなるものとかに使う。

 

トランザクション制御を扱うためのSQL

・BEGIN: 開始の指示。この指示以降のSQL文を1つのトランザクションとする。

・COMMIT: 終了の指示。この指示までを人のSQL文とし、変更するを確定する。

・ROLLBACK: 終了の指示。この指示までを人のSQL文とし、変更するを取り消す。

→ACID特性 の 原子性(1か0か)

 

■似た言葉だけど全然違う、ロールバックとロールフォワード。

・ロールバック…実行した処理を取り消す。SQLの実行失敗やデッドロークなどで発生する。

・ロールフォワード …まだ実行されていない処理を実行する。

障害復旧時、バックアップにより障害前の状態にした後、ログより、障害前から障害直前の状態までデータを更新すること。

 

■設計について

▶︎一般的な設計手順

(1)概念設計

(2)論理設計

(3)物理設計

 

▶︎正規化 ….(2)論理設計の時にする。

・第一正規形:繰り返しの列、重複列がない。

 

・第二正規形:部分従属がない

(例)部分従属とは…{A,B}→C = A→CまたはB→C

 

・第三正規形:推移従属がない

※推移従属とは…{A,B}→C = A→BかつB→CでB→Aではない。

(例)クラス→出席番号→名前

名前は、クラスと出席番号が特定されないとわからない、そんな関係性。

 

実際読んだ本がこちらです↓

Steve Jobs Ⅰ・Ⅱ (著)ウォルター・アイザック(訳)井口耕二

スティーブ・ジョブズの生き方が

良い面も悪い面も客観的に書かれている本でした。

ジョブズは短期で口が悪い人だったともとれるし、その分素直で人間味があって常に完璧を求めた人だったんだなと感じました。

彼のクリエイティブさには憧れます、すごく。

 

Ⅰでは、生まれてすぐに養子に出され、電気屋の父親に引き取られ、エレキトロニックの世界に惹かれたきっかけが書かれていました。学生時代にはLSDや禅にはまり、ベジタリアンになった話などもありました。ウォズアニックとの出会いからのアップルの創立。ネクスト。

 

Ⅱでは、ピクサー。iPod,iPhone,iPad…iTunes…iCloud。ThinkDifferent。iCEO。リベラルアーツ。がんと戦い、妻の協力でなんとか生き抜いて大好きなAppleのために働いた最期。

 

デザイナーではないのに、形や素材、使いやすさを追求する姿勢は見習いたいと思うけど、とても真似できないです。自分の専門性にとらわれず、IT業界をはじめ音楽業界や映画業界、小売業などの多方面でクリエイティブさを発揮しています。一方、他の人のアイデアをいかにも自分のアイデアかのように言うこともあったというのがリアルでした(笑)実現不可能な事を実現させる、「現実歪曲フィールド」とかいう力はすごい能力ですが悪魔の魔法みたいで恐怖さえ感じました。

 

個人的に、ジョブズが禅の魅力に惹かれて、度々行っていたという京都の西芳寺(さいほうじ)に行きたい欲が積もりました。Googleマップで行った気になってます。苔が素敵でした。

 

登場人物が多いので、頭の中でイマイチ整理できてないです。

もう一回ちゃんと読みたいです。

アップデートしたら、wp-includeの変更きえた。

どうも、寒いですね。

 

WP上級者の方からしたら、この題名で離脱すると思います。
わたしはまだまだWPがわかっておりません。何卒、よろしくです。

 

カスタマイズしたいなら、テーマ(/wp-content/themes/)に手を加えるべきとのことです。
題名通り、WPのアップデートにより変更部分は消されてしまいます!!!

WPってアップデートの時に改定されたフォイルまるごと上書きしちゃうんですよね。

 

例えば、、、

Version 4.9.1
2017年11月29日、WordPress 4.9.1 にて
改訂されたファイル一覧

wp-admin/about.php
wp-admin/includes/class-wp-upgrader.php
wp-admin/includes/file.php
wp-admin/includes/meta-boxes.php
wp-admin/includes/misc.php
wp-admin/includes/plugin.php
wp-admin/includes/upgrade.php
wp-admin/js/theme.js
wp-admin/js/theme.min.js
wp-admin/theme-editor.php
wp-admin/user-new.php
wp-includes/class-wp-theme.php
wp-includes/feed.php
wp-includes/functions.php
wp-includes/general-template.php
wp-includes/script-loader.php
wp-includes/version.php
wp-includes/wp-db.php

参考:https://wpdocs.osdn.jp/Version_4.9.1

 

 

他のバージョンアップの差分ファイルでも大体が
wp-admin/とwp-inclide/以下ですね。
wp-contents/はほとんどないと思っていました。

しかし、wp-content/が変更されることもあるようです。

Version 4.8.3、Version 4.7.3では

wp-content/plugins

Version 4.7.1では

wp-content/themes/twentyseventeen/README.txt
wp-content/themes/twentyseventeen/style.css
wp-content/themes/twentyseventeen/functions.php
wp-content/themes/twentyseventeen/assets/js/customize-controls.js

Version 4.7.4では

wp-content/themes/twentyseventeen/footer.php
wp-content/themes/twentyseventeen/style.css
wp-content/themes/twentyseventeen/functions.php
wp-content/themes/twentyseventeen/template-parts/navigation/navigation-top.php
wp-content/themes/twentyseventeen/template-parts/post/content-excerpt.php
wp-content/themes/twentyseventeen/template-parts/post/content-gallery.php
wp-content/themes/twentyseventeen/template-parts/post/content-audio.php
wp-content/themes/twentyseventeen/template-parts/post/content-image.php
wp-content/themes/twentyseventeen/template-parts/post/content.php
wp-content/themes/twentyseventeen/template-parts/post/content-video.php
wp-content/themes/twentyseventeen/README.txt

Version 4.7.5

wp-content/plugins/akismet/_inc/img/logo-full-2x.png
wp-content/plugins/akismet/_inc/akismet.css
wp-content/plugins/akismet/_inc/akismet.js
wp-content/plugins/akismet/akismet.php
wp-content/plugins/akismet/class.akismet.php
wp-content/plugins/akismet/readme.txt

 

 

バックアップ大事ですね!

 

 

ちゃんとCodeXにも書いてありましたね。

NOTE - wp-includes と wp-admin ディレクトリおよびサブディレクトリ、そしてルートディレクトリ (たとえば index.php, wp-login.php 等)のすべての古いファイルを新しいものに置き換えて下さい。wp-config.phpについては安全ですので心配ありません。 wp-contentディレクトリをコピーする際には注意して下さい。wp-content ディレクトリ全体の置換ではなく、このディレクトリ内からファイルをコピーします。ここには現行のテーマやプラグインが含まれるため保持が必要でしょう。デフォルトや古いテーマを直接書き換えた場合も上書きしないように注意してください。変更が失われます(もっとも、新機能や修正が含まれるため、比較した方がよいですが...)。 最後にファイル wp-config-sample.php を参照して、現行の wp-config.php に追加すべき新しい機能が導入されていないかを確認してください。

 

次はちゃんとGit管理して、差分をじっくり見てみたいなと思います。

PHP Data Object

 

お久しぶりです。
最近、家の周りで工事が大量にされており騒音がひどくちょっとイライラしております。

 

ではでは、PHPをもっと知ろうのコーナーです!
PHPってmysqlなどのデータベースを操作できますよねー
その仕組みとは?ということで、

PDO = PHP Data Odjects

について知ろうと思います!!!

 

 

先ほども申した通り、PHPでデータベースを扱うためには、

PDO(= PHP Data Odjects)というオブジェクトを使います。

 

これにより

▶︎データベースに接続

▶︎データベース操作(SQLの実行)

を行うことができます。

 

 

▶︎データベース接続 …PDOクラスを使う

https://php.net によると

例1 ドライバ呼び出しにより PDO インスタンスを生成する

/* ドライバ呼び出しを使用して MySQL データベースに接続する */
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';

try {
  $dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
  echo 'Connection failed: ' . $e->getMessage();
}

 

ドライバとは?ってなったんで私の中で落としこんだ意味が

ドライバ…データベースを扱うためするためのモジュール(プログラム)

つまりMysqlやPostgreSQL,SQLiteのことですね

 

 

//第一引数でデータベースドライバの種類:データベース名;host名の指定
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';

 

//第二引数でデータベースユーザ名を指定
$user = 'dbuser';

 

//第三引数でデータベースユーザパスを指定
$password = 'dbpass';

 

 

▶︎SQLの実行 …PDOクラス or PDOStatementクラスを使う

ここで疑問を感じたのが、

\PDOStatement::executeとPDO::exec何が違うん?/

ってことです。

 

では、PDOクラスと PDOStatementクラスについて。

https://php.net によると

PDO::exec — SQL ステートメントを実行し、作用した行数を返す

PDO::exec() は SELECT 文からは結果を返しません。 プログラム中で一度だけ発行が必要になる SELECT 文に対しては、 PDO::query() の発行を検討してください。 複数回発行が必要な文については、PDO::prepare() による PDOStatement オブジェクトの準備と PDOStatement::execute() による文の発行を行ってください。

PDO::exec()は実行結果を返すんじゃなくて、行数しか返さないらしい。
そして、プレースホルダーとか使えんぽい。

やってみよう。

テーブルusers
|id|name|score|
|1|taro|0|

 

$db = new PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD);
$sql ='SELECT * FROM users';
//return 0 ...SELECT 文からは結果を返しません。
print_r($db->exec($sql));

 

//プレースホルダーを使ってみる

使いようがなかった。。

//プレースホルダーではないが、、、こうすることはできる(当たり前)

$db = new PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD);
$whereVal = 1;
$sql ='SELECT * FROM users WHERE id ='. $whereVal;
//return 0 ...SELECT 文からは結果を返しません。
print_r($db->exec($sql));

 

 

PDOStatement::execute — プリペアドステートメントを実行する

返り値

成功した場合に TRUE を、失敗した場合に FALSE を返します。

プリペアドステートメント….直訳で準備陳述。

これも実行するするだけ。成功したか失敗したかを返す。
一方、PDOStatement::executeは
PDOStatement::prepareでSQLステートメントをセットして、プレースホルダーとか使えるぽい。

 

$db = new PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD);
$sql ='SELECT * FROM users';
$stmt = $db->prepare($sql);

//return 1(=true) ...成功!
print_r($stmt->execute());

 

//プレースホルダーを使ってみる

$db = new PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD);
$sql ='SELECT * FROM users WHERE id = :id';
$stmt = $db->prepare($sql);

//さっきと同じ return 1(=true) ...成功!
print_r($stmt->execute(array(':id' => 1)));

 

 

 

結果が欲しいのに!ってときはこれ。

PDO::query

PDO::query — SQL ステートメントを実行し、結果セットを PDOStatement オブジェクトとして返す

$db = new PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD);
$sql ='SELECT * FROM users';
foreach ($db->query($sql) as $row) {

  print('id: ' . $row['id'] . '<br>');
  print('name: ' . $row['name'].'<br>');
  print('score: ' . $row['score'].'<br>');

}

 

<まとめ>

・PDOをサクッと直接的にsql実行できる。

・PDOStatementはプレースホルダーとか使って計画的にsql実行できる。

・ 結果が欲しいときはPDO::query