‘PHP’ カテゴリーのアーカイブ

PHPList: 空メールのアドオンがあるらしい

このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加

PHPListでケータイ対応する方法を調査中。
空メールで購読、解除ができるアドオンがあることを発見!

Blank_Mail公開します。PHPListで空メール

これすごいんじゃないの!?と思って試してみようとしたのだけれど、やっぱりというか、共用サーバでは無理みたいである。エイリアスを使って特定ユーザ宛に届いたメールをプログラムに渡して処理するんだけれど、CoreServerは受信メールを自動ではプログラムに渡せない。ここらへんがCoreServerの限界なんじゃないのかなと思うんだけれど…。

ソースを改造してPOP3で受信して処理するようにすればできるんだろうけど、それって即時返信じゃないからなぁ…。CRONでやるにしてもタイムラグがあるし。。。それでもいいんなら、できそうだけどなぁ。。。


WordPress:Ktai StyleとPHPList Form Integration

このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加

ちょっとメモ代わりに。
WordPressで、Ktai Styleプラグインを使ってPHPList Form Integrationプラグインのフォームを出そうとしたら、出なかった。理由は、PHPList Form Integrationでフォームを出すときのコードがショートコードとかじゃなくてHTMLのコメントを使っているので(<!–phplist form–>というもの)Ktai Styleのどこかで消されているようだ。

ちなみに試した各プラグインのバージョンは以下の通り。

  • Ktai Style: 1.74
  • PHPList Form Integration: 1.7

根本的な解決方法かどうかはわからないけれど、
最も簡単だと思われる解決策は、以下の通りかなと。

# /plugins/phplist-form-integration/phplist.phpの最後のほう
# phplist_callbackの呼び出し優先順位を99にしない
//add_filter('the_content', 'phplist_callback', 99);
add_filter('the_content', 'phplist_callback');

要は、Ktai Styleによって<!–phplist form–>が削除される前にphplist_callbackを実行するように修正すればいいんじゃないかということです。これで、携帯で見たときにもメルマガ購読フォームが表示されましたし、購読登録できました。


PHP:cURLでBasic認証

このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加

WordPressのPHPList Form Integrationプラグインを使って、メールアドレス確認なしでメルマガ購読許可できるように設定していたのに、できていなかった。だがPHPList自体には入力したメールアドレスは登録されている。一体何故だ?と思ったら、Basic認証のせいだった。

実は、Basic認証があると登録すらされないので、上の話はBasic認証対応してたのだけど、cURLが2回通信するのに、最初のPHPListにログインする通信でBasic認証してなかった!2回目の通信は成功していたのだけど、1回目の通信が失敗していたからログインできていないせいで一般ユーザからの登録扱いとなり、身元不明扱いになっていた。完全にミスってたなぁ。

$username = 'ユーザ名';
$password = 'パスワード';
curl_setopt($ch, CURLOPT_USERPWD, $username . ":" . $password);
// curlによるその他のオプション設定・通信は省略

PHP:WordPressのプラグインでsession_start()

このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加

WordPressでsession_start()するのを、読み込みページ用関数が呼ばれた先頭でやっていたら、エラーが出ていた。あかんやん。タイミング的には確かに、もうページ表示してる途中だから、どこかでechoされてたらアウトなわけです。ということは、session_start()するタイミングは、initだ!

add_action('init', 'hoge_session_start');
function hoge_session_start(){
  session_start();
}

これでエラー出なくなった。


PHP:PHPListをCORESERVERで動かす

このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加

メルマガをWordPressでできないか?ということについて、以前に調査していたのだが、やりたいことに該当する方法ではなかったので、オープンソースのメルマガ発行ソフトのPHPListを使うことにしようかと思って調査したのでメモ。ちなみにWordPressとPHPListを繋ぐPHPList Form Integrationというプラグインがあるのでこれを使う予定。

参考にさせていただいたサイト

ではいきまーす。

  1. まずはここからPHPListの日本語化されたものをダウンロード。
    http://www.d-ip.jp/download/pivot/entry.php?id=14
  2. ダウンロードしたファイルを解凍し、public_html直下にあるlistsディレクトリをWordPressと同じディレクトリに入れる。
  3. lists/config/config.phpを修正する。インストールするデータベース名、データベースユーザ名、パスワードなどを修正。ここはWordPressと同じものでOK!!あとPLUGIN_ROOT_DIRが原因でエラーが出てたので、コメントアウトしておいた(この辺りはよくわかってない)。TESTの値も0にしておく(そうしないとメール送れないので。後で0にしてもよい。)
  4. PHPがsafe modeで動いてると問題があるかもね!というメッセージが出続けるので、CGIモードで動かすために、lists/admin/.htaccessに以下を追加する。
    AddHandler application/x-httpd-phpcgi .php
  5. CGIモードで動くとphp.iniの情報が変わってしまうので、独自に設定するためにlists/admin/以下にphp.iniを作成する。
    magic_quotes_gpc              = On
    register_globals              = Off
    session.auto_start            = Off
    mbstring.http_input           = pass
    mbstring.http_output          = pass
    mbstring.encoding_translation = Off
    # /tmp以下にセッションファイルが作れないというエラーが出たので、
    # 自分のディレクトリ直下にtmpを生成しておくこと
    session.save_path = "/virtual/********/tmp"
    
  6. http://自分のWordPressのドメイン/lists/admin/にアクセスし、PHPListをインストールする。
  7. 管理者のパスワードを変えておく。
  8. インストールが問題なく終わったら、サンプルでインストールされているリスト(メルマガのこと)をアクティブにしておく(WordPressのプラグイン経由でPHPListを使うため)。
  9. CORESERVERのcronを使ってメルマガ配信するために、シェルスクリプトを作成する。名前はphplist.shとした。
    #!/bin/sh
    wget -q -O - 'http://自分のWordPressのドメイン/lists/admin/index.php?page=processqueue&login=管理者名&password=パスワード' >/dev/null
    

    このファイルは/virtual/********/phplist.shに置いた。実行権限を与えておくこと(705)。

  10. CORESERVERのcronに/virtual/********/phplist.shを登録する。
    普通のサーバのcronならば、

    */15 * * * * /virtual/********/phplist.sh
    

    でよいと思うのだが、CORESERVERでは分に入力できる文字列が2文字までみたいなので、*/15と入力できなかった!やっていいのかどうかはわからないが、4行分使って、

    0 * * * *  /virtual/********/phplist.sh
    15 * * * *  /virtual/********/phplist.sh
    30 * * * *  /virtual/********/phplist.sh
    45 * * * *  /virtual/********/phplist.sh
    

    と設定しておいた。
    これで15分毎にチェックされ、キューに入っているメルマガが15分毎に配信されるはず。

さっきまで試していたことなので、だいたい合っているはず。

WordPressのプラグインであるPHPList Form Integration
の設定については後でまた書きたいと思う。


PHP:MBFpdfでバグ!!["]が出力できない

このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加

MBFpdfでバグを発見した!!バージョンは1.0b。
["](ダブルクォーテーション)が出力できないというものだ。

$l+=$ascii ? $cw[$c] : $hwkana ? 500 : 1000;

上のソースの$cw[$c]の$cにダブルクォーテーションが入ってるのだが、
undefined index ” と言われてしまう…。
そこで、$cwをprint_rで表示してみたら、
array(…,[\"] => 500, …);
という記述を発見。ダブルクォーテーションあるけれど、バックスラッシュでエスケープされてるじゃないか!?まあこれが正しいと仮定した場合、$cw["]は定義されていないわけだから、$cが["]の場合、$c = ‘\”‘;にしてしまえばいいんじゃないかと思ったので、mbfpdf.phpに手を入れることを決意!!

MBMultiCellメソッドを修正。

//Get next character
$c=$s[$i];
// 以下3行を追加
if($c === '"'){
	$c = '\"';
}

その後、MBWriteメソッドを修正。
行番号は、上記の作業後なので、この付近と思ってください。

//Get next character
$c=$s[$i];
// 以下3行を追加
if($c === '"'){
	$c = '\"';
}

こうしたところ、ダブルクォーテーションがPDFファイルに出力できた。


PHP:PECL::ssh2のインストール

このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加

PHPでssh2を使う必要が出てきた。
方法としては、PECL::ssh2をインストールしておけばよいらしい。
依存ライブラリとして、libssh2が必要なので、yumにてlibssh2をインストールしておく。
libssh2-develはいらないかもしれない。

yum -y install libssh2 libssh2-devel

その後、peclコマンドでssh2拡張をインストールする。

pecl install ssh2
downloading ssh2-0.11.0.tgz ...
Starting to download ssh2-0.11.0.tgz (22,884 bytes)
........done: 22,884 bytes
5 source files, building
running: phpize
Configuring for:
PHP Api Version:         20041225
Zend Module Api No:      20060613
Zend Extension Api No:   220060519
 1. libssh2 prefix? : /usr

1-1, 'all', 'abort', or Enter to continue: all # libssh2.soへのprefixが/usrではない場合、修正
libssh2 prefix? [/usr] : /usr/lib
 1. libssh2 prefix? : /usr/lib
1-1, 'all', 'abort', or Enter to continue: # 何も入力せずにenterを押す
# インストールが始まる
...
# インストール完了通知
Build process completed successfully
Installing '/usr/lib/php/modules/ssh2.so'
install ok: channel://pear.php.net/ssh2-0.11.0

ssh2.soがインストールされたので、権限を変更する

chmod 755 /usr/lib/php/modules/ssh2.so

php.iniを修正してextensionを組み込む。自分の環境では、extensionの組み込みが外部ファイル化してあったので、そちらを修正する。gd.iniとかをコピーしてssh2.iniを作り、それを修正した。その後は、apacheの再起動を行う。

cd /etc/php.d
cp gd.ini ssh2.ini
vi ssh2.ini
# gdをssh2に変更
extension=gd.so
↓
extension=ssh2.so
# 編集終了

# apacheの再起動
service httpd restart

これで、phpinfo()を確認したところ、ssh2が組み込まれていたのでOK!!


WordPress: cforms2 & Ktai-style

このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加

WordPressのプラグインのcforms2とKtai-Styleの併せ技一本を狙う。
お客さんが携帯サイトをやっていて、携帯からのお問い合わせに対応したいと。しかし、携帯からのお問い合わせで送信されてくるメールが文字化けするんで助けてください!と後輩から頼まれたというのが経緯。

WordPressのフォーラムより、
携帯からの場合は文字コード変換処理を入れるとかの対応が必要だと思います (Ktai Style の is_ktai() 関数を使えばいけそう)。
という情報を手に入れたので、cforms2のソースコードに手をいれて、携帯の場合の処理を追加することにした。
ちなみに、cformsのバージョンは11.0です。

/wp-content/plugins/cforms/lib_validate.phpの先頭に追加。

// 携帯のアクセスの場合のみ、検証の前にUTF-8にエンコードしてしまう。
if(function_exists('is_ktai')){
  if(is_ktai()){
    foreach($_REQUEST as $key => $value){
      $_REQUEST[$key] = mb_convert_encoding($value, 'utf-8', 'auto');
    }
  }
}
// 以下略

次に、/wp-content/plugins/cforms/lib_email.phpを編集。
@mailを@wp_mailに全部変更する。
ここは@mailで検索すればいいのでソース省略。

次に、/wp-content/plugins/cforms/cforms.phpの354行目あたりを修正。

### start with form tag
// $content .= $ntt . '<form enctype="multipart/form-data" action="' . $action . '" method="post" class="cform'.( $cformsSettings['form'.$no]['cforms'.$no.'_dontclear']?' cfnoreset':'' ).'" id="cforms'.$no.'form">' . $nl;
// au でメール送信できないため、enctypeを除去
$content .= $ntt . '<form action="' . $action . '" method="post" class="cform'.( $cformsSettings['form'.$no]['cforms'.$no.'_dontclear']?' cfnoreset':'' ).'" id="cforms'.$no.'form">' . $nl;

これで、開発環境のほうは、メールの文字コードがutf-8で送信できるようになり、携帯からのお問い合わせにも文字化けしなくなった。しなくなったのだが、、、。

本番環境(xreaのcoreserver)で文字化けが続いた。
件名が文字化けするのだ。件名に『=?utf-8?B?44C(略)』と表示された。

調査すること3時間。遂に解決!!原因はWP Multibyte Patchの設定だった。
utf-8でエンコーディングされている件名をiso-2022-jpで解釈してるために化けているみたいだった。

/wp-content/plugins/wp-multibyte-patch/wpmp-config.phpを修正。
ない場合は、wpmp-config-sample.phpをコピーしてwpmp-config.phpを作成して修正。

// wp_mailに対してのパッチを外す
$wpmp_conf['patch_wp_mail'] = false;

ちなみに、上記の設定をtrueにしたままパッチプラグインの/ext/ja/config.phpでUTF-8を使うように指定したら、何故かさらに文字化けた。本文までiso-2022-jpで解釈されてしまった。UTF-8って指定したのに!!このあたりはまだよくわかっていない箇所なので、もっといい設定があるのかもしれない。

最後に、cformsのmy-functions.phpを修正する。
携帯でのアクセスの場合のみ、検証処理後に出力に用いられるデータをutf-8にエンコードしておく。

// 値の検証後、出力前にコールされる関数
function my_cforms_filter($POSTdata){
	if(function_exists('is_ktai')){
		if(is_ktai()){
			foreach($POSTdata as $key => $value){
				$POSTdata[$key] = mb_convert_encoding($value, 'utf-8', 'auto');
			}
		}
	}
	return $POSTdata;
}

これで、パソコンと携帯からお問い合わせフォームを利用してみたが、どちらも文字化けせずにメールが届いた!後輩も喜んで一件落着!!


WordPress: 自作プラグインでAjaxする正しい方法

このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加

WordPressの自作プラグインでAjaxする方法で、正しく行う方法がないか探していた。Googleで検索しても、Ajaxを使ってるプラグインの情報がたくさん出てくるばっかりで、作り手に有益な情報を調べるにまでいけなかった。だから、必要なファイルのみを無理矢理require_onceで読み込んでインスタンスを生成してから、やりたい処理を行うという強引な方法を取っていた。しかし、Ajaxしたいところで毎回require_onceをやるのは面倒だし、正しくやる方法があるに違いないと思っていたら、あったよ!やっぱり!

http://wpdocs.sourceforge.jp/AJAX_in_Plugins

上のサイトの例では、javascriptライブラリとしてSACKを使っているが、俺はprototype.js&scriptaculousファンなので、prototype.jsを使ったAjaxで勝負!

まず、プラグイン側でjavascriptファイルを読み込む設定を行う。
プラグインの名前は、hogeとします。

/**
 * /wp-content/plugins/hoge/hoge.php
 *
 * 管理画面でjavascriptを読み込む
 */
add_action('admin_enqueue_scripts', 'hoge_script_admin');
function hoge_script_admin($hook_suffix){
  // 指定したページのみでjsを読み込むために、条件を設定
  // ここではhogeプラグインのカテゴリー管理ページに焦点と絞ったとする
  if (preg_match('/page_hoge_category_list$/', $hook_suffix)) {
    // hoge_category.jsと、prototype.jsを読み込む
    wp_enqueue_script('hoge_category', plugins_url('hoge/js/hoge_category.js'), array('prototype'), '1.0', false);
  }
}

次に、hoge_category.js側に処理を記述する。
関数 update_category_list が呼ばれると、Ajaxでカテゴリーリストを更新する想定です。

function update_category_list(){
  // ajaxurlはWordPressが定義してくれてる
  var params =[];
  // Ajaxアクションを指定
  params.push('action=hoge_get_category');
  // あとは必要なパラメータを設定
  params.push('abc=xyz');
  new Ajax.Updater(
    'category_list', // 更新される領域のID
    ajaxurl,
    {
      method: 'post',
      parameters: params.join('&')
    }
  });
}

最後に、hoge_category.jsから呼ばれるサーバ側の処理を記述する。

// ajaxで呼ばれるアクションを追加する
add_action('wp_ajax_hoge_get_category', 'hoge_get_category');
// 実際に呼ばれるアクションを定義する
function hoge_get_category(){
  $output = '<ul>' . "\n";
  for($i = 1; $i < 10; $i++){
    $output .= '<li>カテゴリーその'. $i .'</li>' . "\n"
  }
  $output .= '</ul>' . "\n";
  echo $output;
}

これで、カテゴリーリストがAjaxで更新されます。


PHP: switch文の中でcontinueはbreakと同じ

このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加

先日、開発中に、以下と似たようなコードになった。

<?php
  // 削除対象IDの配列
  $delete_ids = array();
  foreach($articles as $article){
    switch($mode){
      case 'delete':
        // 削除モード
        switch($article['category']){
          case 'book':
          case 'music':
            // 本と音楽の記事のみ追加
            array_push($delete_ids, $article['id']);
            break;

          default:
            break;
        }
        break;

      default:
        break;
    }
  }
  // 記事を削除する
  $db->delete($delete_ids);

  $insert_articles = array();
  foreach($articles as $article){
    switch($mode){
      case 'delete':
        switch($article['category']){
          case 'book':
          case 'music':
            // 削除済みなので、インサートしないためにcontinue
            continue;
            break;

          default:
            break;
        }
        break;

      default:
        break;
    }
    array_push($insert_articles, $article);
  }
  // 何故か本と音楽のものまでインサートされる!
  $db->insert($insert_articles);
?>

こうしたら、削除したはずの記事まで復活してしまったという感じ。
うーん、ちょっと例を書くのに失敗したなぁ…。摩訶不思議な仕様のやつだったから、オブラートに包みながらソースを再現させるのが難しい…。

まあそれは置いといて、削除対象は無視してcontinueしてるのに、どうもcontinueされてないのは何故だと。調べてみたところ、switch文中のcontinueはbreakと同じらしい。continueを使いたかったら、continue 2を使えだと…。

PHP:switchの中でcontinue from Side-B

だが、switch文のネスト内でcontinue 2をしてみても、駄目だったので(外のswitch文に制御が戻っただけ?)、フラグを使って対応した。

  // 削除は同じ。インサートのみ変更
  $insert_articles = array();
  foreach($articles as $article){
    $book_music_flg = false;
    switch($mode){
      case 'delete':
        switch($article['category']){
          case 'book':
          case 'music':
            $book_music_flg = true;
            break;

          default:
            break;
        }
        break;

      default:
        break;
    }
    if($book_music_flg){
      continue;  // switch文を抜けてからcontinueしたらOK
    }
    array_push($insert_articles, $article);
  }
  $db->insert($insert_articles);
?>

ちょっとした罠だった。