PHP********* 10

Download Report

Transcript PHP********* 10

プログラム言語「PHP」の
概念とその有用性
by 古庄
自己紹介






古庄と申します
Webでは「がる」というハンドルでふらついております
本職は技術者です。現役プログラマーやってます
あわせて設計とかインフラとか教育とか色々やってます
引っかかりやすいGoogle向けキーワードとしては「古庄
道明」「エンジニア 親方」「エンジニア 禅」「がる」あたりで
しょうか。
あちこちのサービスで「gallu」ってIDでふらふらしてます

はてな、twitter、github など
PHPのメリットってなに?


PHPを学ぶのに「ほかの言語のほうがよくて、PHPを学ん
でもあんまり意味がない」と、ちょっと悲しいので
今「なぜPHPなのか」を再確認してみましょう
Web用に作られた言語



「Webアプリケーション」を作る上で、このあたりはいろい
ろと便利だしありがたいですね
典型的には、スーパーグローバル変数の$_POSTと
$_GET、$_COOKIEあたりが顕著です
使う頻度は少ないですが、$_FILESも便利ですね
学習的に、敷居が低い


いくつか「但し書き」はつきますが(その辺は後述)、入り
口が広くて敷居が低いのは、原則、メリットです
登り続ける必要がある「山脈」であるのはあらゆるプログ
ラミングにおいて共通ですが、敷居が高いと、上る前に
へこたれます orz
環境的に、敷居が低い


レンタルサーバで、PHPが「使えない」ところのほうが少な
いですね
自力でサーバを立てるにしても、比較的インストールに
手間がかかりません
案件的に、メリットが高い

案件単価などではJavaのほうが高いことも多いですが、
数量的にはPHPが大変に多いです
PHPのデメリット?


一般的に言われているデメリットを検証してみましょう
良しと悪しは、双方ともちゃんと向き合うべきものです
重い / 遅い


比較対象にもよります
実際に「重い / 遅い」ケース


C言語とかと比較すると圧倒的に重いし遅いですね。なので、
PHPで「OSを書く」とか「デバイスドライバを」とか「組み込み
が」とか考えるのはやめましょう
差異がないケース


よく一時期比較されていたPerlだと、さほど大きな差異はない
です
それ以外でも。処理が100~200msほど変わるケースは時々
見かけますが、それが「本当に意味のある数値であるかどう
か」は、状況次第です
セキュリティ的に脆弱



一時期言われていた「嘘」です。どの言語で書いても、そ
の辺に言語差異はたいしてありません
かつ、現在良書があるので、PHPはむしろ、Webセキュリ
ティ的には「学びやすい環境が整っている」ので、他言語
より安全なものが作りやすい学習環境は整っています
ただし、もちろん「学ばずに」プログラムを組めば、見事
なほどに脆弱なものができあがります

でもそれって、別に言語によらず… orz
HTMLとロジックが分離されてない


たしかにPHPでもありますが、PerlやJavaのWebアプリ
ケーションでも十分に見かけます
テンプレートエンジン、みんな使いましょうね!!(笑
動的型付き言語は危ない


いわゆる「型宣言のない」言語ですね
…実際まぁ、危ないです



でもそれいったら、JavaScriptとかどうするんだろう…
なかなか難しいですが、型はできるだけ意識しておきま
しょう
よかったら「2a問題」でググってみてくださいませ
PHP驚愕の事実
if ('2a' == 2) {
ここ通る
}
global変数 / 変数のスコープ

global変数はまぁ「使わないように」しましょう



それはどこでも一緒
危なさについては、後で例題を
変数のスコープは「関数」単位までで、{} によるブロック
スコープは存在しないので気をつけましょう

でもこれも、最近ない言語増えてるし…
「PHPは初心者に優しい」という嘘





「導入の敷居が低い」のは事実です
でも、プロとして「一定レベルのコードを書くために必要な
経験値と知識と熟練度とレベル」ってのは当然あります
間違っても「学ばずに書ける」とか「学習量が少ない」と
かって意味ではありません。
この「導入の敷居が低い」と「プロとして要求される品質」
の間にある乖離を感じ取ってください
プログラムは「言語」です。「日本語が読み書きできる」と
売り物として「詩が書ける / 説明書が書ける / 小説が書
ける」は、全然意味が違います。
php.iniという存在



………実際困りものではあります orz
ここは本当に「デメリット」ですが。知識があれば、その落
とし穴へのはまり込みを最小限に食い止めることはでき
ます!!
自分にとっての「定型パターン」をあらかじめ作っておく
のもよいですね
プログラミング初心者の為のTips

まずは「PHPほとんどわからない」人のためのTips

「これからPHPを始める人」用のTipsですが、いくつかは、
その後でも十分に役に立つテクニックだったりはします
nameアトリビュート

<input name=“hoge”>

デザイン的に「一番意味のわからない」アトリビュート
ですが、PHP的には「これがないと始まりません」!!
「どんな名前か」までを含めて大切なので、PHPエンジニ
アと協議のうえ、適切な名前でお願いいたします


hiddenのお話し

<input type=“hidden” name=“” value=“”>

データの持ち回りなどによく使います
hiddenは「簡単に改ざんできます」!!
時々「設定情報をhiddenに入れる」ものを見ますが、厳に
慎みましょう


formのmethod






<form action=“./hoge.php” method=“post”>
<form action=“./hoge.php” method=“get”>
<form action=“./hoge.php”>
これもPHP的に重要ポイントです。
formの場合、九分九厘postです
一応、エンジニアと確認はとっておきましょう
checkboxの[]





<input type=“checkbox” name=“hobby”>
これだと「複数のチェックが取得できない!!」
<input type=“checkbox” name=“hobby[]”>
これが正しい!!
これは「PHPに固有の書き方」なので、他言語では存在し
ないので気をつけてください!
エラーが出た!



シンタックスエラーの出し方
特に共有サーバで多いのですが「エラーが出ない(画面
真っ白)」ってのがあります
エラーメッセージはどの言語でも有効ですが、PHPは「割
合と丁寧なエラー出力」なので、なおのこと重要です!
この「エラーメッセージ」のon/offは、php.iniで設定されて
います

本来的には、以下の記述でエラー出力をonに出来ます
//
ini_set('display_errors', 'on');
error_reporting(E_ALL);
E_ALLの中身(の一部)

E_ERROR


E_WARNING


コンパイル時のパースエラー
E_NOTICE


実行時の警告 (致命的なエラーではない)
E_PARSE


重大な実行時エラー
実行時の警告。エラーを発しうる状況に遭遇したことを示す
などなど
例)関数のtypo




php.iniを読み込む(エラー出力:off)
phpファイルを読み込む
phpファイルの中を解析する
解析したphpファイルを実行する


関数の行。関数を探しに行く



ini_setでエラー出力がonになる
関数が見つからない
エラーを出力
終了
例)シンタックスエラーの場合



php.iniを読み込む(エラー出力:off)
phpファイルを読み込む
phpファイルの中を解析する


解析でエラー
エラーを出力、でも出力がoffなのでなにもしない

終了

…いや終了言われても、シンタックスエラー出てこないと
困ります orz
シンタックスエラーの出し方その1

一つは .htaccess に書く
php_value display_errors 1
php_value error_reporting 32767
シンタックスエラーの出し方その2



もう一つは「別のphpファイルからinclude」
ファイル名は適当に、たとえばt.phpで用意します
検査対象のファイル名を「hoge.php」と仮定します
<?php
ini_set('display_errors', 'on');
error_reporting(E_ALL);
include(‘./hoge.php’);
エラーが出た! シンタックスエラーの潰し方

エラーは出たけど「どこが」間違ってる?

この調査が早いほど「最終的なプログラムの仕上がり」
は早くなりますし、ここで「ドはまり」すると、いくらでも時
間は浪費されていきます

ちなみに、有効なメソッドを2つ


一服、休憩、一寝入り
ベアプログラミング(not ペアプログラミング)
シンプルケース

エラーが発生している行か、その上の方でエラー
1
2
3
4
5
<?php
$i = 10;
$test = 'test'
echo $i , $test , "\n";
Parse error: syntax error, unexpected 'echo'
(T_ECHO) in /home/furu/t.php on line 5
面倒なケース

以下のパターン。どこがエラーかわかります?
1
2
3
4
5
6
7
8
9
10
11
<?php
//
$no = 10;
for($i = 0; $i < $no; $i ++) {
echo $i , "\n";
}
//
$test = 'test;
if ($argv[2] == $test) {
echo ('ok');
}
Parse error: syntax error, unexpected 'ok' (T_STRING) in /home/furu/t.php on line 10
まずは「全体的に」コメントアウト
1 <?php
2 /*
3 $no = 10;
4 for($i = 0; $i < $no; $i ++) {
5
echo $i , "\n";
6 }
7 //
8 $test = 'test;
9 if ($argv[2] == $test) {
10
echo ('ok');
11 }
12 */
少しづつコメントアウトから出してみて
1
2
3
4
5
6
7
8
9
10
12
13
14
<?php
//
$no = 10;
/*
for($i = 0; $i < $no; $i ++) {
echo $i , "\n";
}
//
$test = 'test;
if ($argv[2] == $test) {
echo ('ok');
}
*/
ifやforは、ブロックの中をコメントアウト
1
2
3
5
6
7
8
7
8
9
10
12
13
14
<?php
//
$no = 10;
for($i = 0; $i < $no; $i ++) {
/*
echo $i , "\n";
*/
}
/*
$test = 'test;
if ($argv[2] == $test) {
echo ('ok');
}
*/
1
2
3
4
5
6
7
8
9
10
11
12
<?php
//
$no = 10;
for($i = 0; $i < $no; $i ++) {
echo $i , "\n";
}
/*
$test = 'test;
if ($argv[2] == $test) {
echo ('ok');
}
*/
で…見つける!!
1
2
3
4
5
6
7
8
9
10
11
12
<?php
//
$no = 10;
for($i = 0; $i < $no; $i ++) {
echo $i , "\n";
}
$test = 'test;
/*
if ($argv[2] == $test) {
echo ('ok');
}
*/
デバッグの基本


落ち着いてこつこつと、一つづつ丁寧に
一番使っちゃいけない単語は「出来ているはず」「ちゃん
とここは通ってるはず」「この変数には正しいデータが
入っているはず」


できている「はず」なら動く「はず」だよね?
きちんと、var_dumpなりprintなりで「通っている証拠」を
出しましょう。エビデンス、って言い方をします
「技術者と会話が出来る」レベルのTips


「書けるかは自信がないけど」会話はできる、くらいのレ
ベルは、一つ「目安にする」ところです
これが出来ると「技術者に、お願いと依頼と相談と交渉と
締め上げが出来る」ので、大変に重宝がられます
includeとrequire


*_onceってのもありますね
細かい使い分けは以下の通り



includeはファイルがないときにfalseを返し警告が発生します
requireはファイルがないときにE_COMPILE_ERROR レベルの
致命的なエラーを出します
_onceが付くと、同じファイルの読み込み重複は無視します

まぁrequireのほうが処理としては安全です

以降、includeと書いてあったら、特に但し書きがない限り
「includeとrequireのどちらにもいえる話」です
includeファイルはどこにあるの?



./と書いてあったら、実行ファイルと同じディレクトリです
書いてない場合は、どこを探しにいくのでしょうか?
調査用コードと、たとえばの結果
<?php
var_dump( get_include_path() );
string(20) " . : /usr/local/lib/php"

ほかの場所にファイルを置きたい場合の方法
//
$path = 'ファイルを置きたいディレクトリの絶対パス';
set_include_path(get_include_path() . PATH_SEPARATOR . $path);
includeしたファイルの?>と改行

サンプル
<?php
$i = 10;
echo $i , "\n";
?>


?>の後の改行が、時々悪さをします
「テンプレート使って、phpファイルにはプログラムしか書
いていない」前提で。
?>は「書かない」ほうが圧倒的に安全です

「よそ様のincludeファイル」に ?>と改行があって如何とも
しがたい場合の場当たり的回避策
<?php
ob_start(); // 回避策 start
require_once('他人様のライブラリ.inc');
require_once('他人様のライブラリ2.php');
ob_end_clean(); // 回避策 end
// 以下、普通にコードを書く
何かのタイミングで¥が増殖する…


「addslashes」がonになっていると予想されます orz
一応先に。 addslashesは「百害あって一利なし、何があろ
うともゼッタイに絶対に使ってはいけない」設定です




類似品: register_globals
でも、たまにonだったりします orz
その場合、プログラムの先頭でとりあえず回避しておき
ましょう
回避用のコードはあちこちで検索できるので、省略
ちょっとした修正なら出来そうな人へのTips


簡単なコードなら書ける、直せる、くらいのレベルの人向
けのTipsです
ここらあたりから、場合によっては「初級の技術者」として
のお仕事が選択肢の可能性として存在し得ます
コメントについて




実際「超」が付くほど重要です!!
「コメントがなくても理解出来るような、わかりやすい命名
と流れるようなロジック」は重要です
でもそれはそれとして「コメントを書く」必要があります
コメントには「こんな事をしたい」という気持ちを書きましょ
う。その気持ちの「表現方法」として、プログラム言語が
あります
「日本語で」プログラムを書こう




まずは「日本語で」「箇条書きで」何をやるかを細かく書
いてみましょう
その「書かれた日本語」で、何をやるかが明確に理解で
きますか?
理路整然とした「箇条書きの指示」が書けたら、それを
「コメント」として残しておいて、そこからプログラムを書い
てみましょう
ちゃんとコメントも残せるので一石二鳥です
プログラムが「書けない」理由




プログラムが書けないのは「PHPでどう書くかわからない
から」じゃない
「プログラム的にどう分解したらいいかわからない」から
もうちょっと突っ込むと「何をやるか」が理解しきれてない
から
だからこそ、まずは慣れている「日本語」で、箇条書きで
「何をするか」を細かく書きましょう
インデントについて


丁寧に入れましょう。バグのいくつかが防げます
ifやforの「 {} の省略」は避けましょう!!
if (条件式)
hoge_true_call();
foo_call();
if (条件式)
hoge_true_call();
hoge_true_call2();
foo_call();
エラー出力とメッセージ

プログラム中にエラーメッセージを入れるのはやめましょ
う。後々、運用で面倒です。
テンプレートエンジンは「ロジックとデザインの分離」です。
プログラムはロジックだし、エラーメッセージは「デザイ
ン」の仲間です。

次のPageで具体例を。

エラー出力とメッセージ:駄目な例
$smarty->assign('name_error', '名前は必須です<br>');
{$name_error}
名前:
<input type="text" id="form_name" name="name">
望ましい例
$smarty->assign('name_error', true);
{if true == $name_error}
名前は必須です<br>
{/if}
名前:
<input type="text" id="form_name" name="name">
「コピー&ペースト」の危険性



「やむを得ない」かもしれませんが危険です
実際締め切りがあるので、その瞬間はやむを得ないかも
しれない
でも、コピペして「理解しないまま」そのソースを使い続け
ると、何か問題が起きたときに瞬時に手詰まりします




意図する動きにならなかった
実は元のソースコード(の、特に異常系)にバグがあった orz
修正や変更の依頼があった
その他諸々
「技術者+デザイナー」を目指す人のTips


この辺から「初級の、職業技術者」向けレベル、くらいに
なります
普通に「初級技術者」としても食っていける、くらいのレベ
ルを想定しています

えぇもちろん、そこから「上級技術者」までには、険しくて深くて
ハードな壁がいくつもあるんですが…
var_dumpとxdebug






おいちゃんは var_dump派です
デバッグの基本は「おかしなところを見つける」です
必ずあるのが「うまくいってる、はず」
うまくいってるはずなら、動くはずです
基本は、変数の丁寧なvar_dump
とはいえxdebugは便利なので「環境が許せば」選択肢に
入れておきたいところです
実例
// 設定
static $conf = array(
'www.google.co.jp' => array('param' => 'q', 'name' =>'Google'),
'beta.search.yahoo.co.jp' => array('param' => 'p', 'name' =>'Yahoo!(サーチベータ)'),
);
//var_dump($conf);
// uriの分解
$awk = explode('/', $uri, 4);
//var_dump($awk);
// ある?
if (true === isset($conf[$awk[2]])) {
//print "true\n";
// 取得
$awk2 = explode('?', $awk[3], 2);
//var_dump($awk2);
globalの恐怖(デバッグしにくい)

最近減りましたが。globalは「駄目!ゼッタイ!」

「書式は」知識としては大切です(試験にも出るしね!)
実務的には「絶対に使わない」

// 初期化
$dbh = NULL;
// DB接続
function db_connect() {
global $dbh;
try {
$dbh = new PDO($dsn, $id, $pass);
} catch (PDOException $e) {
error_log($e->getMessage());
exit;
}
// 静的プレースホルダ
$this->conn_->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
}
function hoge() {
global $dbh;
if ($dbh == NULL) {
db_connect();
}
// 以下、いろいろな処理
}
function foo() {
global $dbh;
if (NULL == $dbh) {
db_connect();
}
// 以下、いろいろな処理
}
function bar() {
global $dbh;
if (NULL === $dbh) {
db_connect();
}
// 以下、いろいろな処理
}
function boo() {
global $dbh;
if ($dbh = NULL) {
db_connect();
}
// 以下、いろいろな処理
}
処理をまとめる(リファクタのしかた)



「8割がた似た処理のコピペ」の連打は、システムとエン
ジニアと会社の寿命を縮めます
最低でも関数、できればクラスにまとめましょう
すでに動いているものをどうやってまとめるか、の1案
まず「共通処理を書くところ」を作る

適当な場所に、まずディレクトリを切ります


libsとかそんな名前が最近は多いですね
こんなファイルを作ります。ファイル名は一端、たとえば
「common_lib.php」とかでもよいでしょう
<?php
/*
* 共通になる処理を書く場所
*/
切り出す



処理が「全く同じ」ところを見つける
修正する「前に」テストする
「全く同じ」処理を「共通」に切り出す


5カ所も6カ所も散らかっている場合、まずは「1カ所」
修正後にもう一度テスト
「8割方」似たような処理は

切り出せそうならがんばる
悩んだら、相談できる相手がいるなら相談する
相談できない時は「コメントで」一言書いておく

例


// ここの処理、xxxのファイルのnn行目とほとんど一緒だけど
// 共通化できないかなぁ?
特に共通化したほうがよいもの





定数のたぐい(消費税計算とか)
認証処理
データの読み書き(特に書き)
「課金処理」など、重要な遷移
validate処理
学び方

読書する



書く。ひたすらにコードを書く


巨人の肩の上に立つ
古人の糟魄
質量転換
人に見てもらう

github
最後に3つ


いや「好きな言葉」とか、出しているときりがないのです
が
ランダムに3つほど切り抜いて持ってきてみました
ドラゴンクエスト-ダイの大冒険:稲田浩司

魔法使いの魔法ってのはな仲間を守るためのものなん
だ。無数の呪文と知識をかかえ、皆の危機をはらうのが
魔法使いの役目だ

よく覚えてとけ。魔法使いってのはつねにパーティーで、
一番クールでなけりゃならねえんだ。全員がカッカしてる
時でも、ただ一人氷のように冷静に戦況を見てなきゃい
けねえ。
ONE PIECE:尾田栄一郎

いいかい 優しさだけじゃ人は救えないんだ!!
人の命を救いたきゃそれなりの知識と医術を身につけ
な!!!
腕がなきゃ 誰一人救えないんだよ!!!
学び続ける力:池上彰

すぐ役に立つことは、すぐに役に立たなくなる
それよりも、すぐには役に立たないけれど、 社会に出て
から、じわじわと効いてくる学問を やったほうがよほどい
い
ラスト



学習速度は人によっても違いますし、同じ人でも「常に同
じ速度で伸びる」とか、ないです
ただ「継続している人」は、確実に伸びます
一番危ないのは「PHPをマスターした」人





「マスターした」って、何を指してるんでしょう?
どこまで行ったら「マスターした」ことになるんでしょう?
「十で神童 十五で才子 二十過ぎれば只の人」
ほとんどの仕事がそうでしょうが「一生涯が修行」です
楽しみつつ学びつつ、でやっていける一助になれば望外
の幸いです!!