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をマスターした」人
「マスターした」って、何を指してるんでしょう?
どこまで行ったら「マスターした」ことになるんでしょう?
「十で神童 十五で才子 二十過ぎれば只の人」
ほとんどの仕事がそうでしょうが「一生涯が修行」です
楽しみつつ学びつつ、でやっていける一助になれば望外
の幸いです!!