大嵌り、Create Table
物凄く嵌った。
時間というより、精神的ダメージが大きい。
何をしたかというとCreate Tableである。
ローカル環境でテストして動いていた。
SQL文自体は、MySQLAdminでエクスポートしたものだから間違いはない。
これがいけなかった。
サーバに入れてテストすると、何と動かない。
それだけでは流石に焦らない。
MySQLAdminのSQL実行で試した。
エラーが出れば良い。
が、エラーにならない。
ここで盛大に焦る。
もしかしてエスケープかとも思ったが、エスケープしてみて(mysql_escape_string使用)も動かない。
かなり絶望感が沸いてくる。
SQL文は正しく、ローカルでは動いたから間違いはないという先入観(というか事実だが)が、他にエラーの可能性があるという考えを持たせてくれなくなるのである。
サーバのせいだろう、権限か、などいらぬことばかりが頭を駆け巡る。
こういう時に便利なのがこれである。
echo mysql_error();
MySQLAdminのSQL実行でエラーが出ないのに、エラーになっているのだから、これしかない。
このmysql_error()は、直前の実行されたエラーについて返してくれるスグレモノなのだ。
見ると訳の分からないエラーが出ている。
内容は普通に文法エラーなのだが、文法エラーなどあるはずがない。
ローカルで動いているMySQLAdminが作ったSQL文なのだから。
だが、エラーだというのだから仕方がない。
と、先入観というのは恐ろしいものである。
エラーだという箇所で、一番怪しいのは、文法的に間違いではなく、ふたつのクエリを連続して記述している点である。
ローカルでは動いていたのだが・・・
もしかしたら、2つはダメなのか。
分けて、ひとつづつテーブルを作るようにすると・・・
動いた・・・
MySQLAdminでは動くのに、ローカルでは動くのに、何と理不尽なことだろうか。
MySQLのバージョン違いによる差だとしか考えられない。
MySQLのバージョンを知る手っ取り早い方法は次のクエリ実行である。
select version();
ローカルが、5.0.51b-community
サーバが、5.0.45-log
微妙に違うだけだが、それこそ微妙に違うのもまた事実である。
分かり辛かった・・・
PHPでcookieの操作
cookieの操作は基本だが、意外と使いづらい。
それはPHPの仕様(というかバグ)のせいだと思う。
PHPでのcookie出力は他のヘッダ出力前でなければならない。
まあ、それは仕方ないとして、ヘッダを出力していないのにエラーになることがある。
どういうときかというと、日本語がコメントでも何でも存在した後はダメなのだ。
ヘッダではないコメントでアウトなのだから、バグだと思う。(最新のPHPは分からないが)
コメントを英語にするか取り去ると通るのだから意地悪だ。
どこにcookie出力を書いてもいいようにするには他の手を考えなければならない。
コメントに日本語を使いたいし、処理の中で、先頭以外でcookie処理をしたいことだってあるのだから。
どうするかというと、PHPからcookieを書かせない。
Javascriptを使うのである。
それなら、ロード完了時にJavascriptで書き込めるので、PHPの最後に処理しても問題ない。
PHP側
$wkCookie="document.cookie = 'キー名称 = 値;expires=継続時間;";
$smarty->assign('Cookie',$wkCookie);
テンプレート側
{if $Cookie!=""}
{/if}
ちなみに、受け取りはもっと簡単である。
PHP側 $cookie=$_COOKIE["キー名称"];
はてなへブックマークボタン
はてなブックマークにブックマークするボタンを作ろう。
<a href="http://b.hatena.ne.jp/append?サイトURL"> <img src="http://b.st-hatena.com/images/append.gif" title=""このエントリをはてなブックマークに追加”> </a>
サイトURLはhttpから始まる記事のフルURLである。
画像はダイレクトにリンクしているが、ダウンロードして自サイトから貼った方がベターだ。
はてなブックマークのFirefoxアドオンを入れていると、ブックマークするボタンが表示されるようになる。
なぜか、相手URLが「http://b.hatena.ne.jp/entry/add/サイトURL」になっている。
「append」ではなく、「entry/add」なのだ。
どちらでもいいということだろう。
同様に他のソーシャルブックマークのボタンも作れる。
pingback(ピンバック)のこと
トラックバックに似ているものにピンバックがある。
自動的に相手サイトとやりとりをしてこちらへのリンクを作るというものだ。
トラックバックでの問題点を改善しようということでできたものである。
何をするかというと、こちらのブログに相手へのリンクを含めた記事を書く。
トラックバックでは相手のトラックバックアドレスが必要だが、ピンバックでは相手の記事のアドレスになる。
書きましたよ、という訳だ。
それだけで相手がリンクしてくれるはずがない。
そのための仕組みがある。
まず、こちらのシステムが、こちらの記事内にリンクがあることを発見しなければならない。
発見すると、そのリンク先(記事のアドレス)から必要な量を受け取り、その中に「X-Pingback ヘッダ」もしくは「pingback link タグ」があるか探す。(先頭に近い部分に置くと負荷が減るだろう)
どいういうものかというと、こういうものだ。
ヘッダ X-Pingback: http://blog.ks2.info/xmlrpc.php リンク <link rel="pingback" href="http://blog.ks2.info/xmlrpc.php" />
これはこのページ(ブログシステム)のものである。
見つからないと、相手はピンバックに対応していないので諦める。(!)
見つかると、pingback linkにあるアドレスに「XML-RPC コール」を送る。
相手側が処理(もちろんリンクも確認する)して、こちらへのリンクを作る。
どうしてこんなことをしているかというと、実際にリンクが張られた場合にのみピンバックしようということである。
トラックバックで言えば、相手内にこちらへのリンクがあることを確認してから、こちらが張るようにするのと同じ理屈だ。
トラックバックは簡単にHTMLからPOSTしても実現できたという点もある。
SPAMを無くそうということだろう。
やることは、実はこれまで作ってきたトラックバックと大差ない。
リンクを探し、送る内容をピンバック仕様にして、受け取りも用意してやるだけである。
トラックバックをちょっと直せばできるだろう。
が、実装すべきか?
ちょっとペンディング。
トラックバックはレガシーな雰囲気を醸し出すのであった方がブログっぽい。
というか、トラックバックがあるとブログにしか見えない。
まあ、「はてな」などのソーシャルブックマークを使った方が良いかもしれない。
Twitterも。
なお、Twitterに送信しておくと、設定で自動的にはてなにブックマークができるそうだ。
Twitterへの送信はもう調べてあるので、すぐに実装可能である。
参考URL
Pingback 1.0 仕様
ちなみに、はてなにブックマークされているか調べてみた。
はてなブックマーク > 新着ブックマーク
ここでURLを入れると検索してくれる。
このブログもブックマークされていた。
トラックバック送信後、戻り値の確認
トラックバックを送信するのはフォームでもできる。
送りっぱなしである。
ちゃんとやるなら、相手の戻りを確認しなければならない。
送りっぱなしなら簡単だし、待ち時間もいらない。
それもひとつの選択肢ではあるが・・・
とりあえず戻り値を確認するようにしよう。
XML形式で戻されるが、前に書いたように「<error>戻り値</error>」の部分だけ解釈しても良い。
「0」なら成功、それ以外なら失敗である。
さてどうやるか。
XAMをパースして、連想配列に入れて、そこから読み出して・・・
面倒である。
ヒントは、エラータグで囲まれた部分だけが必要で、しかもそのタグは1回しか出てこないのである。
関数内だとして・・・
// ソケットオープン
if (!$sock = fsockopen($host , 80 , $errNo , $errStr , 3)){
return "Socket Open Error";
}
// 送信
fputs($sock , $senddata);
//相手からの戻りを受け取る
while(!feof($sock)){
$res = fgets($sock);
}
//戻り値を取り出す
return preg_match_all("|<error>(.*?)</error>|","", $res);
最後のpreg_match_all部分で取り出せる。
1行である。
もうちょっと細かくやるなら、「0」以外ならメッセージを取り出すと良いだろう。
PHPでトラックバックの送受信(追加)
送る場合は、ソケットをfsockopenして、適当なヘッダ(無視されないため)を付けたPOSTデータをfputsする。
POSTするのは、前の記事に書いた4つである。
沢山サンプルがあるので、検索するとすぐに見つかるだろう。
受ける側は、$_POSTで各項目を受け、いくつかのチェックを行う。
相手のURLのページを読み込むのは次のように書く。
$buff = @file_get_contents($url);
$urlに日本語やスペースがある場合はurlencode()する必要があるが、URLの部分をエンコードするとうまく読み込めない。
また、条件を統一するために、読み込み前にいくつか設定しておくと良いかもしれない。
ini_set('allow_url_fopen', 1);
ini_set("user_agent", "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
ini_set('default_socket_timeout',60);
概要の中や相手ページに日本語があるかチェックするのは、次のように書く。
if(!preg_match('/[一-龠]+|[ぁ-ん]+|[ァ-ヴー]+|[a-zA-Z0-9]+/u', $buff)){
日本語がない場合の処理
}
相手に戻すのは単純に作成したxml部分をechoで返すだけ(他にechoしない)である。
PHPでトラックバックの送受信
トラックバックを処理するようになると、もうブログである。
実は簡単に実装できる。
トラックバックは、相手がこちらの記事に対し行うもので、された方は相手先を表示、つまり相手にリンクするものである。
相手はというと、何も制限がないから、こちらとは無関係にトラックバックを送信できるようになっている。
それでは不公平であり、そのためにSPAMも多い。
相手先にこちらへのリンクを要求することが増えているのも道理だろう。
なぜこんなことになるかというと、トラックバックの送信は単なるPOSTデータだからである。
送りっぱなしでいい(エラー処理をしない)なら、HTMLだけで、サーバがなくてもできてしまう。
actionにリンクを張らせたいところのトラックバックURLを指定して、自分のURLをPOSTするだけという手軽さなのだ。
なので、トラックバック要求時に相手にこちらへのリンクがあるかチェックする。
日本語があることも条件としたい。
こちらのトラックバックURLは通常URLと同じにしたいと考えた。
便利だし、判りやすい。
通常はトラックバックを受けるプログラムを指定したURLとなっているが、記事のURLでトラックバックしようというのだ。
画期的だと思うのだが・・・どうだろう?
必要なことはふたつ。
トラックバックを受けること、トラックバックを送ることである。
前者は随時受信し、後者は記事の登録時に送信する。
まずは送信である。
必要項目は4つ。
title : 記事のタイトル url : ブログのURL ・・・ 必須 excerpt : 記事概要(本文) blog_name : ブログの名前
これを相手のトラックバック先にPOSTするのだが、ソケットを使って開き、fputsする。
このあたりは更新pingと同じである。
相手から結果が返ってくるので、エラー処理をして完了となる。
受信は通常URLにするのでトラックバックであることをチェックしなければならない。
とはいえ、必須のURLがPOSTされているかだけのこと。
URLがPOSTされていれば、トラックバック処理をして、されていなければ、通常の表示を行えばよい。
ここで問題がある。
相手が入れてきた本文に自URLがあるかチェックするのか、相手URLを開き、自URLがあるかチェックするか、である。
前者は簡単だが、確実性には乏しい。
やはり相手のURLから受信して内容を確かめるのが確実となる。
単に自URLを検索するだけだから、大した手間でもないだろう。
ということで、URLがPOSTされていたら、そのURLを開いて読み込む。
ソケットではなく、PHPではファイルとして処理できてしまう手軽さである。
その中に自URLがあるかどうか、日本語を含むかどうかをチェックする。
結果をエラーで返すが、xmlである。
とはいえ、定型でよい。
正常時 <?xml version="1.0" encoding="UTF-8"?> <response> <error>0</error> </response> エラー時 <?xml version="1.0" encoding="UTF-8"?> <response> <error>1</error> <message>元記事へのリンクが見つかりませんでした</message> </response>
この他に、送信・受信したトラックバックの管理や、記事へトラックバックを表示することもしなければならない。
こちらからは、更新の都度本文が変わっている可能性があるので送信することになる。
また、同一記事に同じURLでトラックバックがあった場合には、前のトラックバックを表示しないようにして、新しい方を表示しなければならない。
これから作るので、この記事は後で直すかもしれない。
上記は現時点での内容である。
「?id=xxx」を「xxx」にする方法
ApacheのRewriteを使って、次のようなことがしたい。
「http://cum.2box.jp/?id=xxx」あるいは、
「http://cum.2box.jp/index.php?id=xxx」というのではなく、
「http://cum.2box.jp/xxx」としたい。
拡張子がないので、フォルダに見える。
拡張子をダミーで付けても良いが、そこまではしないでいいだろう。
簡単なのは、プログラムを何も直さなくても動く方法である。
まあ、実際はクローラーやrssのために、その形にリンクを直す作業は出るのだが、受け側は変える必要がない。
何かと言うと、最初に書いてある。
入ってきたリクエストを書き換え、理解できる形に変えてからプログラムを呼び出そうというのだ。
記述はこれ。
Options FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([0-9]+)$ index.php?id=$1 [L]
実はハマった。
サブフォルダの中なのだが、サーバ設定で直接そのフォルダにリダイレクトされる。
その書き方で試行錯誤してしまった。
何が悪かったかというと、URLから見るとルートになるので、頭に「/」を付けていてうまく動かなかったのである。
何も付けないとちゃんと動いた。
ちょっとだけ解説すると、「RewriteEngine On」で書き換えを有効にする。
次の2行は、ファイルになくフォルダにもないとき、という意味で、ない場合にのみ書き換えるようにしている。
最後が実際の書き換えで、数字のみだった場合に、「?id=」に変換してから、実際に動作させるのである。
ページ内部のリンク、およびrss.xmlとsitemap.xmlも、その形に直した。
すっきりしたリンクになり、SEO対策的にも良いとされている。
ただし、今まで「?id=xxx」で作って不利だったとも思えないので、ページ内容によるのかもしれない。
「パパも」などはその形だが、ちゃんとクロールされている。
Javascriptでのz-index指定
どうしてか指定がうまくいかなかった。
「styles.z-index」と書いていたからである。
「styles.zIndex」だった。
うまくいくはずがない。
コロンビアのドメイン
コロンビアのドメインが国内限定から、地域無制限になるという。
「.co」だから、良いかもしれない。