requireとincludeの違い

サンプルコードはこちら↓
https://github.com/kin29/php

・requireVsInclude.php

・once.php

 

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

・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ネタを書きます。

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

Githubにもコミットしてますう。
https://github.com/kin29/php/blob/master/src/passArgument.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される、まさしくニコイチ!

 

 

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

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

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