目次:ITかあさんの楽しいPHP入門
PHPの入門書なんて難しかったり、物足りなかったり、サンプルスクリプトが実用的でなかったり。
楽しくて今すぐ使いたくなるPHPのスクリプトを紹介&解説。
主催しているLinuxお勉強しよう会で紹介したPHPネタもこちらで解説していきます。
PHPの入門書なんて難しかったり、物足りなかったり、サンプルスクリプトが実用的でなかったり。
楽しくて今すぐ使いたくなるPHPのスクリプトを紹介&解説。
主催しているLinuxお勉強しよう会で紹介したPHPネタもこちらで解説していきます。
PHPの登竜門!PHPメールフォームを今更ですが 解説してみたいと思います。
大抵一番最初に作るPHPのプログラムチックなモノと言えばメールフォームですが、はっきり言ってめちゃめちゃ難しいです。
PHP●年やっている私も、たまに頭を抱えるメールフォームの事例もありますから決して侮ってはいけません。
この2つの戦いですが、これが難しいです。
ですから、今回なら$_Postと$_Sessioこの2つの使い方が分かればよいと思います。
後はコピペで メールフォームの項目を自分で増やせたら それでOKなのです。
色々ありますが、今回のケースならsession_start()と、mb_send_mail()の2つを覚えて、残りの文字コードに関する設定のあたりは決まり文句のように
コピペして 『テクマクマヤコン・テクマクマヤコン』と覚えて下さい。
と、ツッコミ入れてくる坊やがいると思いますが、ナンセンス!
極力面倒な処理はjQueryのフォームのバリデータを使ったほうがリアルタイムで入力チェックしてくれますし、
最低限悪さが出来ないような処理だけ入れてあげればいいんです。
入門なので、極力使う関数は少なめにして、すぐにメール送信が実行できるようにしましょう。
Linuxエンジニアの方と一緒に主催している勉強会で『スクレイピング』についてリクエストを頂いたことがきっかけで『WEBサイト上で表示されているテキストやリンクなどのDOM要素をスクレイピングで簡単に引っこ抜いてしまおう!』ということになりました。
人生初のスクレイピング体験となりましたが非常に簡単!ではいってみよ~
DOM要素として必要な部分だけを抽出して、ほとんどの場合自分のデータベースに登録して実際には運用したりします。
WEBサイトは著作権で守られています。許可無く勝手に人様のサイトから情報だけ抜き出して自分のサイト上に公開することは出来ません。この著作権の問題には十分注意してください。
スクレイピングの方法はいくつか存在するのがですが、私はSimple HTML Domを好んで使っています。色々調べた結果、個人的にはこれが一番使い易いと思いました。
サイトからダウンロードし、simplehtmldom_1_5フォルダをスクレイピングを実行したいサーバーにアップして、simple_html_dom.phpを呼び出すだけで準備は完了します。
簡単ですが、データの引っこ抜き方です。『ここを引っこ抜きたい!』という部分を指定します。
下記の赤字部分に注目。引っこ抜きたい(スクレイピングしたい)DOMの指定。
id=”contents”の中のulを引っ張りたいなら
DOMの指定が#contentで、#を使えて入れ子にするあたりが全くCSSの指定と一緒なのでWEBデザイナーにも優しい設計です!
ITかあさんのブログ内をスクレイピング実行して、どのように抜き出せるのか実際にやってみましょう。
例えば、ITかあさんのブログのトップページ中のリンク(hrefの中身)を引っ張るとしたらこうなります。
// simple_html_dom.phpファイルの読み込み
include_once('simplehtmldom_1_5/simple_html_dom.php');
//スクレイピングしたいURLを指定
$html = file_get_html( 'http://www.kaasan.info/' );
//リンク
foreach($html->find('a') as $element)
echo $element->href . '<br>';
これだけでは何のリンクなのか分かりません。引っ張るaタグの範囲を右カラムのリンクに絞ります。
// simple_html_dom.phpファイルの読み込み include_once('simplehtmldom_1_5/simple_html_dom.php'); //スクレイピングしたいURLを指定 $html = file_get_html( 'http://www.kaasan.info/' ); //○○の中のある特定の要素もCSSと同じように指定できます。 foreach($html->find('#rightcol .category_list a') as $element) echo $element->href . '<br>';
もちろん画像のみの抽出も可能でして // simple_html_dom.phpファイルの読み込み include_once('simplehtmldom_1_5/simple_html_dom.php'); //スクレイピングしたいURLを指定 $html = file_get_html( 'http://www.kaasan.info/' ); //画像URL保存用の空の配列を用意 $src = array(); //リンク foreach($html->find('img') as $key => $element){ $src[$key] = $element->src; } foreach($src as $img){ echo '<img src="'.$img.'">'; }
もっと細かく要素を指定したい場合はこちらが参考になります。
スクレイピングしたDOMをforeachのループ中にINSERT文を実行すれば簡単に自分のwordpressに記事として登録することが出来ます。
以下はさくらvps設定マニュアルの投稿記事一覧を抽出してWordpressをインストールしたデータベースに、記事としてINSERTする方法です。
MDB2.phpは大手レンタルサーバーなら大抵インストールされているかと。(私mysql関数って使ったことないんですよ・・)
require_once 'MDB2.php';//ライブラリのロード //DSN $db = "mysql://ユーザー名:パスワード@localhost/データベース名?charset=utf8"; //接続 $mdb2 =& MDB2::factory($db); //フェッチモード設定 $mdb2->setFetchMode(MDB2_FETCHMODE_ASSOC); // simple_html_dom.phpファイルの読み込み include_once('simple_html_dom.php'); // UTF-8で処理 他の文字コード処理するかもしれないからdefineしておく。 define("CHAR_SET","UTF-8"); // 文字化け対策のおまじない的(?)なもの。 mb_language("Japanese"); $html = file_get_html( 'http://www.kaasan.info/archives/category/さくらvps設定マニュアル' ); //wordpress上の投稿日時 $wordpress['date'] = '2012-02-12 10:00:00'; foreach( $html->find( '#content ul' ) as $ul ) foreach( $ul->find( 'li' ) as $li ) $mdb2->exec("INSERT INTO `wp_posts` (`post_author`, `post_date`, `post_date_gmt`, `post_content`, `post_title`, `post_excerpt`, `post_status`, `comment_status`, `ping_status`, `post_password`, `post_name`, `to_ping`, `pinged`, `post_modified`, `post_modified_gmt`, `post_content_filtered`, `post_parent`, `menu_order`, `post_type`, `post_mime_type`, `comment_count`) VALUES (1, '{$wordpress['date']}', '{$wordpress['date']}', '$li', 'test', '', 'publish', 'open', 'open', '', 'test', '', '', '{$wordpress['date']}', '{$wordpress['date']}', '', 0, 0, 'post', '', 0)");
サンプルは以上です。
どこをどのように引っ張るのか、アイディア次第でいろんなサイトやサービスがお手軽に作れそうですが、著作権などの問題には十分注意してください。
前回の記事でRSSをsimplexml_load_string関数を使ってRSSのXMLを表示してみました。でも、ちょっと見にくいし、分かりずらいので、自由に自分のほしいデータを持ってこれるように 配列構造を変更して、より配列に慣れ親しんでいこうと思います。
配列が分かればPHPが分かります。
ずばり、
です。
前回の記事の最後の方にちょっとxmlオブジェクトのままだと扱いにくい点に触れましたが、
それならば扱いやすい配列の形に変換すればいいんです。
最初の2つのxmlオブジェクトとして展開するまでは前回と何も変わっていまん。
少し変わったのが、そのまま$xml->channel->item->$i->title;をechoで出力せず、
一度$rss[$i][‘title’]に代入してあげている点です。
実際に連想配列にする処理は以下。とってもシンプルですね。
//フィードを取得したいRSSのURLを記述 $contents = file_get_contents('http://www.kaasan.info/feed'); //XMLをオブジェクトに変換 $xml = simplexml_load_string($contents); //連想配列作成用に、新規で空の配列を用意する $rss = array(); for ($i = 0; $i <= 9; $i++) { $rss[$i]['title'] = (string)$xml->channel->item->$i->title; $rss[$i]['description'] = (string)$xml->channel->item->$i->description; $rss[$i]['date'] = (string)$xml->channel->item->$i->pubDate; $rss[$i]['link'] = (string)$xml->channel->item->$i->link; }
for文のループについては前回の記事を参考にしてもらうとして、大事なのが2つ。
まず配列とは、タンスのイメージです。
引き出しの中にデータが入ります。
ただの変数では引き出しがありません。
引き出しが無いなら空の配列を代入することで新たに引き出しを作ってあげればいいんですね。
たったコレだけ空の配列が出来、配列として代入することが出来るのです。
新たに配列を作りたいときには有効ですのでぜひ覚えて下さい。
作った配列をprint_rして出力してみましょう。
実行例
RSSをそのまま出力したものと比べるとぐっと見やすくなったのが分かりますか?
RSSをそのまま出力
今まではrssの情報をすべて出力していましたが、今回新規で作った配列$rssは必要な部分だけ選んで配列化していますから、
とても見やすいですね。
最後の仕上げです。作った$rssをHTMLの中に書いて、きれいにRSSを表示してみましょう!
今回は非常に簡単だったのでループをもう一つ新しいものを覚えておきましょう。
foreach文です。
for文は
としたように、$iがいくつから始まり,いくつまで繰り返すかを必ず指定しなければなりませんでしたが、
foreachはfor文と違い、問答無用で配列のある文だけループします。
たったこれだけです。初心者にはfor文が直感的で分かりやすいという意見もありますが、
PHPではforeachの方がやや実行が早いというメリットもありますので
for文の特性を利用した『配列中の何番目から何番目!』という決まりが無く、配列全て出力するのであればforeachを使うのがよいでしょう。
foreach($rss as $val)となっていたら、$valにデータを代入しているようなイメージでいてください。
<dl> <?php foreach($rss as $val):?> <dt> <a href="<?php echo $val['title'];?>"> タイトル:<?php echo $val['title'];?></a> </dt> <dd>ディスクリプション:<?php echo $val['description'];?></dd> <dd>日付:<?php echo $val['date'];?></dd> <?php endforeach;?> </dl>
またはこんな書き方も出来ます。
<dl> <?php foreach($rss as $val){ ?> <dt><a href="<?php echo $val['title'];?>">タイトル:<?php echo $val['title'];?></a></dt> <dd>ディスクリプション:<?php echo $val['description'];?></dd> <dd>日付:<?php echo $val['date'];?></dd> <?php } ?> </dl>
ただ、これでは実際に } 閉じるタグがfor文の閉じタグなのかforeachの閉じタグなのかどちらなのか分からりにくいので個人的には上の方をオススメします。
これは何回目のループなのかを出力したいなら、キー名の出力の仕方を覚えるとよいです。
<dl> <?php foreach($rss as $key => $val):?> <dt>第<?php echo $key;?>回目</dt> <dt><a href="<?php echo $val['title'];?>">タイトル:<?php echo $val['title'];?></a></dt> <dd>ディスクリプション:<?php echo $val['description'];?></dd> <dd>日付:<?php echo $val['date'];?></dd> <?php endforeach;?> </dl>
実行例
以上でRSSの出力についてはおしまいです!
2012年02月12日に開催したLinuxお勉強しよう会でPHPとXMLを使って遊ぼうというネタを紹介させて頂きました。
そこでのネタの詳しい解説としてまずはXMLとは何か?という根本的なところから初めていきます。
XMLとは『コンピューターが認識するためのことば』です。
例えばHTMLはあくまでも人間が目で見て『これは何だ』と認識するものですが、コンピューターはHTMLを見ても内容を解析することは出来ません。
そこでXMLを利用するわけです。
XMLの代表的な例はRSSがあります。
RSSとはブログなどの更新情報を配信などをしているところです。
RSSが配信されているサイトだと(このITかあさんのブログもRSSが配信されているのですが)このようにURLのアドレスバーにアイコンが表示されます
ブラウザによって表示に誤差があるもののRSSをブラウザによって表示すると以下の画像のような表示になるかと思います。
このRSSをリーダーを使って購読するとこのようになります。
HTMLそのままだとレイアウトを変更するなりして、自分のサイトの一部分に組み込んだりすることは難しいですが、
RSSを配信することのメリットはGoogleリーダーで読み込んだり、自分のブログなどに設置して2次利用しやすくなります。
日本人はよほどIT企業に勤めていたりでもしなければRSSを購読してブログやサイトの更新情報をチェックする人は少ないかもしれません。しかもたくさんの人に購読されたからと言ってSEOに効果があるわけでもありません。
しかし、RSSはXMLという言語で作られているのでちょっとPHPをかじったレベルの人であればいとも簡単に自分のサイト内に表示させることが出来ます。
RSSというXML言語で作られたものを配信することによって誰かに2次利用してもらえることが期待出来、最終的にはめぐりめぐって自分のサイトのSEOに繋がるかもしれません。
そんなわけでPHPとXMLを使ったおもしろくて実用的なコンテンツの作り方を学びたいと思います。
PHPを使ってRSSを自分のサイトやブログの好きなところに表示させてみたいと思います。
RSSはXMLという言語を使って出来ています。XMLについての詳しい解説はこちらを確認して下さい。
RSSを表示してあげるには、
1.表示したいRSSのURLを指定するfile_get_contents関数
2.XMLとして開く関数を実行するsimplexml_load_string関数
$contents = file_get_contents('http://www.kaasan.info/feed'); $xml = simplexml_load_string($contents);
なんと、たったのこれだけで準備は完了です。
$xmlの中身がどうなっているのか、念のために参照してみます。
一つの変数($なんちゃら)に複数の値が入っているデータを配列をいうのですが、この配列構造になっているデータを参照するのに使う関数がprint_rまたはvar_dumpです。私も日ごろPHPで何かプログラミングをしていて、一番お世話になっている関数です。
$contents = file_get_contents('http://www.kaasan.info/feed'); $xml = simplexml_load_string($contents);
//$xmlの中身を参照。preタグで囲うと見やすくなる。 echo '<pre>'; print_r($xml); echo '</pre>';
もしかしたらこの画面を見たことのある人もいるかもしれません。よくこれだけで『エラーです!どうにかしてください!』といわれるんですが、『あ、これ今デバック中なので・・・・』みたいなやりとりをよくWEBデザイナーの方としていますw
実はこの時点ですでにRSSをHTML内に表示する準備は出来ているんです。
細かい解説は後にして、ひとまず表示だけ先にしたいと思います。
<dl> <?php for($i = 0; $i <= 9; $i++):?> <dt><a href="<?php echo $xml->channel->item->$i->link;?>" target="_blank"><?php echo $xml->channel->item->$i->title;?></a></dt> <dd><?php echo $xml->channel->item->$i->description;?></dd> <dd><?php echo $xml->channel->item->$i->pubDate;?></dd> <?php endfor;?> </dl>
この画像は$xml->channel->itemの中身です。RSSの中身をprint_rしているURLと合わせて確認して下さい。
print_rで$xmlの中身を参照したとき、RSSをURLで確認して、件数を一つずつ数えると10件ありますが
PHPやJavascriptなどプログラミング言語では配列のカウントは0から数えるという大事な決まりごとがあります。
$xml->channel->itemの中身は分かっても、それがどういう仕組みでループされているかがピンと来ないかもしれません。私も生まれて初めてPHPでループをした時はピンときませんでした。
そこで$iを出力しながら実行してみましょう。
<dl> <?php for($i = 0; $i <= 9; $i++):?> <dt>第<?php echo $i;?>番目のループ</dt> <dt><a href="<?php echo $xml->channel->item->$i->link;?>" target="_blank"><?php echo $xml->channel->item->$i->title;?></a></dt> <dd><?php echo $xml->channel->item->$i->description;?></dd> <dd><?php echo $xml->channel->item->$i->pubDate;?></dd> <?php endfor;?> </dl>
$xmlをprint_rで参照したものと、RSSの実行2を比べてみましょう。
$iには数字が1ずつ増加していることが2つを比べると理解できると思います。
応用編として、好きなところだけを表示したいとします。例えば3番目から6番目。
(プログラム上、配列は0番目からカウントするのをお忘れなく)
for内の数字を変更すればいいだけです。
<dl> <?php for($i = 3; $i <= 6; $i++):?> <dt><a href="<?php echo $xml->channel->item->$i->link;?>" target="_blank"><?php echo $xml->channel->item->$i->title;?></a></dt> <dd><?php echo $xml->channel->item->$i->description;?></dd> <dd><?php echo $xml->channel->item->$i->pubDate;?></dd> <?php endfor;?> </dl>
逆順にする方法もあります。配列の順番を入れ替える関数もあるんですが、もっと簡単に。
$i++で1ずつ増えるので$i–で1ずつマイナスにする方法もあるんです。
こうすればさっきと逆順になりますね!
//10番目から1ずつマイナスに <dl> <?php for($i = 9; $i <= 0; $i--):?> <dt><a href="<?php echo $xml->channel->item->$i->link;?>" target="_blank"><?php echo $xml->channel->item->$i->title;?></a></dt> <dd><?php echo $xml->channel->item->$i->description;?></dd> <dd><?php echo $xml->channel->item->$i->pubDate;?></dd> <?php endfor;?> </dl>
ループしないで最新1件だけがほしい!1件だけならループの必要がない?
最新1件だけのタイトルだけを出力するとして・・・
<?php echo $xml->channel->item->0->title;?>
どうでしょう?エラーですね。$ループされていたとき$inには数字が入っていたのだから、そのまま数字を書けばいいんじゃないの?
と思ってしまいますよね。これはちょっとした落とし穴でして。
演算子って言われてもイマイチピンときませんが、数字はあくまでも数字であることは分かりますよね。数字は数字。それ以上参照のしようがありませんものね。
オブジェクトでもなんでもないただの数字を展開しようとしたのでここではエラーになってしまったのです。
ちょっと面倒なのですが、この場合直前に$iに0を代入して、変数化してあげれば先ほどと同じ書き方で出力可能です。
<?php $i = 0; echo $xml->channel->item->0->title
; ?>
以上でRSSの基本的な出力方法についてはおしまいです。