memo.xight.org

PHP

2010-03-02 Tue

PHPによるデザインパターン入門 原稿公開

- Summary
PHPによるデザインパターン入門は2009-09-14に絶版となり、原稿を公開。

- Reference
書籍「PHPによるデザインパターン入門」の原稿テキストを公開します - Do You PHP はてな
http://d.hatena.ne.jp/shimooka/20100301/1267436385

PHPによるデザインパターン入門|サポート|秀和システム
http://www.shuwasystem.co.jp/books/7980/1516-4/1516-4.html

PHPによるデザインパターン入門 - Do You PHP?
http://www.doyouphp.jp/book/book_phpdp.shtml

Google ブックス - PHPによるデザインパターン入門
http://books.google.co.jp/books?id=sXNh4TeQeBIC

2010-01-13 Wed

PHPでTwitter APIのOAuthを使う方法

- Summary
PHPでTwitter APIのOAuthを使う方法。
PEARの HTTP_OAuthを利用する。

1. Twitter での操作
  1-1. Twitter にアプリケーションを登録する。
  1-2. Consumer Key と Consumer secret を取得する。

2. アプリケーションからTwitter APIを利用する。
  2-1. リクエストトークンを取得する。
  2-2. 認証用 URL を取得する。
  2-3. ユーザーから承認を受ける (bot の場合は自分でやる)。
  2-4. アクセストークンを取得する。
  2-5. API にアクセスする。

- 1-1. Twitter にアプリケーションを登録する。
Register a new application からアプリケーションを登録する。

Application Name from XXXの部分にあたる。日本語も可能。
Description アプリケーションの説明文。
Application Website アプリケーションのウェブサイト。Application Name のリンク先URLを指定する。
Organization アプリケーションを管理する組織名。
Website 組織のウェブサイト。
Application Type Browser を指定すると、ユーザーがアクセス権を承認したあと、 Callbak URL にリダイレクトする。Client を指定した場合は「クライアントソフトに戻ってこのコードを入力してね」と表示される。
Callback URL Application Type を Browser にした場合に入力する。ユーザーがアクセス権を承認した後、この URL にリダイレクトする。サービスの URL が確定してない場合は、仮で入れておくか Application Type を Client にしておいて、後で設定しても良い。
Default Access type アプリケーションに与えられる権限。Read & Write か Read-only か。
Use Twitter for login 自分のアプリケーションで「Sign in with Twitter (Twitter でログイン) 」を利用する場合はチェックを入れる。

- 1-2. Consumer Key と Consumer secret を取得する。
アプリケーションを登録すると、 Consumer KeyとConsumer secretが取得できます。
こんな感じです。
クリックして拡大

- 2. アプリケーションからTwitter APIを利用する。
HTTP_Request2 は デフォルトで ssl_verify_peer が true になっている。
デフォルトのまま使うと Twitter と SSL 通信するときに
Unable to connect to ssl://twitter.com:443
のエラーになってしまうため、 ssl_verify_peer を false にして accept

$consumer_key = '[1-2で取得したConsumer key]';
$consumer_secret = '[1-2で取得したConsumer secret]';
 
include 'HTTP/OAuth/Consumer.php';
$consumer = new HTTP_OAuth_Consumer($consumer_key, $consumer_secret);
 
$http_request = new HTTP_Request2();
$http_request->setConfig('ssl_verify_peer', false);
$consumer_request = new HTTP_OAuth_Consumer_Request;
$consumer_request->accept($http_request);
$consumer->accept($consumer_request);
 
session_start();
 
// リクエストトークン を取得
$callback = '[Twitter に登録した Callback URL]';
$consumer->getRequestToken('https://twitter.com/oauth/request_token', $callback);
 
$_SESSION['request_token'] = $consumer->getToken();
$_SESSION['request_token_secret'] = $consumer->getTokenSecret();
 
// 認証用 URL を取得
$auth_url = $consumer->getAuthorizeUrl('https://twitter.com/oauth/authorize');
 
// アクセストークンを取得する
$verifier = $_GET['oauth_verifier'];
$consumer->setToken($_SESSION['request_token']);
$consumer->setTokenSecret($_SESSION['request_token_secret']);
$consumer->getAccessToken('https://twitter.com/oauth/access_token', $verifier);
 
$_SESSION['access_token'] = $consumer->getToken();
$_SESSION['access_token_secret'] = $consumer->getTokenSecret();


ここまでで、アクセストークンを取得できる。
ここからは、Access Token, Access Token Secret を利用して Twitter APIにアクセスする。

- アクセストークンを利用してAPIにアクセス
$consumer->setToken($_SESSION['access_token']);
$consumer->setTokenSecret($_SESSION['access_token_secret']);
 
$status = 'つぶやきの内容';
$response = $consumer->sendRequest("https://twitter.com/statuses/update.xml", array('status' => $status), "POST");
echo htmlspecialchars($response->getBody());


- Services_Twitter の場合
require_once 'Services/Twitter.php';
require_once 'HTTP/OAuth/Consumer.php';
 
try {
    $twitter = new Services_Twitter();
    $oauth   = new HTTP_OAuth_Consumer(
       'consumer_key',
       'consumer_secret',
       'auth_token',
       'token_secret');
    $twitter->setOAuth($oauth);
 
    $msg = $twitter->statuses->update("I'm coding with PEAR right now!");
    print_r($msg);
} catch (Services_Twitter_Exception $e) {
    echo $e->getMessage();
}


- Reference
PHPでTwitter APIのOAuthを使う方法まとめ - 頭ん中
http://www.msng.info/archives/2010/01/twitter_api_oauth_with_php.php

Twitter API Wiki / Twitter API Documentation
http://apiwiki.twitter.com/Twitter-API-Documentation





2009-12-15 Tue

Twitter bot の作り方

- Summary
Twitter botのスクリプト。

以下の動作が可能。
  - 用意した文章を順番に投稿。
  - 用意した文章をランダムに投稿。
  - reply を受けると、ランダムに文章を返す。
  - 特定の語を含む reply を受けると、特定の文章を返す。

- Reference
プログラミングができなくても作れるTwitter botの作り方
http://pha22.net/text/twitterbot.html

Services_Twitter
http://labs.transrain.net/products/services_twitter/

phaのニート日記
http://d.hatena.ne.jp/pha/

2009-05-24 Sun

PHPMailerでGmailのSMTPを利用する

- Summary
PHPMailerでGmailのSMTPを利用してメールを送信する。
ポート465からSMTP over SSLを利用する。

- Source

<?php
mb_language("japanese");
mb_internal_encoding("UTF-8");
 
require("class.phpmailer.php");
$mailer = new PHPMailer();
$mailer->IsSMTP();
$mailer->Host = 'ssl://smtp.gmail.com:465';
$mailer->SMTPAuth = TRUE;
$mailer->Username = 'user@gmail.com';  // Gmailのアカウント名
$mailer->Password = 'gmail_password';  // Gmailのパスワード
$mailer->From     = 'from@gmail.com';  // Fromのメールアドレス
$mailer->FromName = mb_encode_mimeheader(mb_convert_encoding("Fromの名前","JIS","UTF-8"));
$mailer->Subject  = mb_encode_mimeheader(mb_convert_encoding("メールのタイトル","JIS","UTF-8"));
$mailer->Body     = mb_convert_encoding("メールの内容","JIS","UTF-8");
$mailer->AddAddress('friend@example.com'); // 宛先
// $mailer->AddReplyTo($email, $from);
 
if(!$mailer->Send()) {
   echo "Message was not sent<br/ >";
   echo "Mailer Error: " . $mailer->ErrorInfo;
} else {
   echo "Message has been sent";
}
?>


- Reference
tishon.net - Using PHPMailer with Gmail
http://www.tishon.net/index.php/2008/03/21/phpmailer-gmail/

さぼてん - 2009-02-14 - メールフォーム - PHPmailer+xajax
http://saboten009.blogspot.com/2009/02/phpmailerxajax.html

2009-05-24 Sun

PEAR::MailでGmailのSMTPを利用する

- Summary
Pear::MailでGmailのSMTPを利用してメールを送信する。
ポート587からSTARTTLSを利用する。

- Source

<?php
mb_language("japanese");
mb_internal_encoding("UTF-8");
 
require_once 'Mail.php';
 
$params = array(
  'host'     => 'smtp.gmail.com',
  'port'     => 587,
  'auth'     => true,
  'username' => 'example@gmail.com',
  'password' => 'password',
  'debug'    => true,
);
 
$headers = array(
  'From'    => 'example@gmail.com',
  'To'      => 'example@gmail.com',
  'Subject' => mb_encode_mimeheader(mb_convert_encoding("メールのタイトル","JIS","UTF-8"))
);
 
$recipients = 'example@gmail.com';
$body = mb_convert_encoding("メールの内容","JIS","UTF-8");
 
$smtp = Mail::factory('smtp', $params);
$e = $smtp->send($recipients, $headers, $body);
 
if ( PEAR::isError($e) ) echo $e->getMessage() . "\n";
?>


- Reference
たら風呂 - 2007-04-04 - PEAR::MailでGmailのSMTPを使う
http://d.hatena.ne.jp/taraburo/20070404/1175694545

2007-03-19 Mon

HTML Purifier - HTMLを許可しつつXSS対策を行えるPHPライブラリ

- Usage

$purifier = new HTMLPurifier();
$clean_html = $purifier->purify( $dirty_html );


- HTML Purifier Live Demo
http://hp.jpsband.org/live/docs/examples/demo.php

- Reference
HTML Purifier - Filter your HTML the standards-compliant way!
http://hp.jpsband.org/

- via
phpspot開発日誌 - HTMLを許可しつつXSS対策を行えるPHPライブラリ「HTML Purifier」
http://phpspot.org/blog/archives/2007/03/htmlxssphphtml.html

2007-02-14 Wed

PHPの文字化け - 5つの誤解と5つの対策

- Summary
設定すべき項目は以下.

;; Disable Output Buffering
output_buffering = Off

;; Set HTTP header charset
; default_charset = EUC-JP

;; Set default language to Japanese
mbstring.language = Japanese

;; HTTP input encoding translation is enabled.
mbstring.encoding_translation = off

;; Set HTTP input encoding conversion to auto
mbstring.http_input = pass

;; Convert HTTP output to EUC-JP
mbstring.http_output = pass

;; Set internal encoding to EUC-JP
mbstring.internal_encoding = EUC-JP

;; Do not print invalid characters
mbstring.substitute_character = none

mbstring.detect_order = SJIS,EUC-JP,JIS,UTF-8,ASCII



- 誤解1: default_charsetはデフォルトの文字コードのことではない.
default_charsetは,出力時にHTTPヘッダとして送信する文字コード名のこと.

default_mimetype = 'text/html'
default_charset = 'utf-8' の場合

header('Content-Type: text/html; charset:utf-8');

が自動的に実行される.

Content-Typeが固定されるため,default_charsetは使用すべきではない.

- 誤解2: languageパラメータは内部言語のことではない.
languageパラメータは,mb_send_mailを利用した際にのみ使用される.
また,mb_send_mailは文字コードの変換を指定できないため,使用すべきでない.
で代替可能.
よって,languageパラメータは実質的に意味をなさない.

- 誤解3: internal_encodingは内部エンコードのことではない.
internal_encodingはmbstring関数のデフォルトエンコードのこと.
mb_convert_kanaなどで変換元文字コードの指定がない場合に使用される.

変換元文字コードを固定にするため,
internal_encodingはソースコードの文字コードと揃えておくと良い.

- 誤解4: http_outputを指定しても,自動的に文字コードは変換されない.
http_outputとは,mb_output_handlerが実行された時の出力エンコード.
ob_start("mb_output_handler")

でと指定して初めて使われる.
また,http_outputの動作条件は,出力がtext/htmlである必要がある.

- 誤解5: detect_orderでautoを指定してはいけない.
detect_orderとは,文字コードの自動検出の優先順位のこと.
未指定の場合は,"auto" という値になるが,
"auto" は "ASCII,JIS,UTF-8,EUC-JP,SJIS" に展開される.

マルチバイトを扱う際に,ASCIIが最初にある点が問題.
出力する文字コードを先頭にし,JISやASCIIは最後の方に設定する.

- 結論
対策1: default_charsetを設定しない.
対策2: mb_send_mailを使用しない.
対策3: internal_encodingをソースコードの文字コードと揃える.
対策4: http_outputを使用しない.
対策5: detect_orderは必ず指定する.

- Reference
PHPの文字化けを本気で解決する - ぎじゅっやさん
http://hain.jp/index.php/tech-j/2007/02/13/%EF%BC%B0%EF%BC%A8%EF%BC%B0%E3%81%AE%E6%96%87%E5%AD%97%E5%8C%96%E3%81%91

2007-01-29 Mon

PHPで画像にWatermark 加工

- Summary
二つの画像を合成し,Watermark加工が行なえる.

- Source

function emboss($pic1,$patt) {
	header("Content-type: image/png");
 
	$source=imagecreatefromjpeg($pic1);    // Source
	$pattern=imagecreatefromjpeg($patt);    // pattern
	list($width, $height) = getimagesize($pic1);
	list($widthpatt, $heightpatt) = getimagesize($patt);
	$new_width=$width;
	$new_height=$width/$widthpatt*$heightpatt;
	if($new_height>$height){
		$offset=intval(($new_height-$height)/2);
	}
	elseif($new_height<$height){
		$offset=intval(($new_height-$height)/2);
	}
	else{
		$offset=0;
	}
 
	$image_p = imagecreatetruecolor($new_width, $new_height);
	$pattern = imagecreatefromjpeg($patt);
	imagecopyresampled($image_p, $pattern, 0, 0, 0, 0, $new_width, $new_height, $widthpatt, $heightpatt);
 
	$im = imagecreatetruecolor($width, $height);   
 
	for($y=0; $y < $height; $y++) {
		for($x=0; $x < $width; $x++) {
			$colors=imagecolorsforindex($source, imagecolorat($source, $x,$y));
			$pattern_color=imagecolorsforindex($image_p, imagecolorat($image_p, $x,($y+$offset)));
			//changes brightness depending on luminance
			if(($y+$offset+1)>0 &&($y+$offset)<($new_height-1)){
				$brightness=abs(($pattern_color['red']*50/255)-50);
				if($pattern_color['red']<150){
					$change=true;}
				else{
					$change=false;
					$tally=0;
				}
				if($change&&$tally<2){
					$highlight=1.8;
					$tally++;
				}
				else{
					$highlight=1;
				}
				$brightness = $brightness * $highlight;
			}
			else{
				$brightness=0;
			}
			$r=(($colors['red']+$brightness)>255)? 255 : ($colors['red']+$brightness);
			$g=(($colors['green']+$brightness)>255)? 255 : ($colors['green']+$brightness);
			$b=(($colors['blue']+$brightness)>255)? 255 : ($colors['blue']+$brightness);
 
			$test=imagecolorallocate($im, $r,$g,$b);
			imagesetpixel($im,$x, $y, $test);
		}
	}
	imagepng($im);
	imagedestroy($im);
}
emboss("me.jpg","patternsq.jpg");
//emboss("magic800.jpg","patternsq.jpg");
//emboss("crop.jpg","patternsq.jpg");


<img src="emboss.php" />


- Reference
http://www.ckdog.co.uk/php/imgtests/emboss.phps

Watermarking JPEG and PNG Images with PHP and GD2
http://koivi.com/php-gd-image-watermark/

- via
Merge images / add logo - PHP
http://www.thescripts.com/forum/thread121386.html

2006-12-02 Sat

PHPでオーディオ読み上げCAPTCHAを実現

- Summary

function joinwavs($wavs){
    $fields = join('/',array( 'H8ChunkID', 'VChunkSize', 'H8Format',
        'H8Subchunk1ID', 'VSubchunk1Size',
        'vAudioFormat', 'vNumChannels', 'VSampleRate',
        'VByteRate', 'vBlockAlign', 'vBitsPerSample' ));
    $data = '';
    foreach($wavs as $wav){
        $fp     = fopen($wav,'rb');
        $header = fread($fp,36);
        $info   = unpack($fields,$header);
        // read optional extra stuff
        if($info['Subchunk1Size'] > 16){
            $header .= fread($fp,($info['Subchunk1Size']-16));
        }
        // read SubChunk2ID
        $header .= fread($fp,4);
        // read Subchunk2Size
        $size  = unpack('vsize',fread($fp, 4));
        $size  = $size['size'];
        // read data
        $data .= fread($fp,$size);
    }
    return $header.pack('V',strlen($data)).$data;
}


- Usage
joinwavs(array("1st.wav","2nd.wav","3rd.wav"));


- Reference
splitbrain.org - Joining .WAVs with PHP
http://www.splitbrain.org/blog/2006-11/15-joining_wavs_with_php

Index of /audio
http://bartok.wizbit.net/audio/

- via
phpspot開発日誌 - 2006-12-01 - PHPでオーディオ読み上げCAPTCHAを実現する方法
http://phpspot.org/blog/archives/2006/12/phpcaptcha_1.html

2006-11-30 Thu

PhpUnit - PHPのユニットテスト自動化ツール

- Reference
SourceForge.net: PhpUnit
http://sourceforge.net/projects/phpunit/

PHPUnit
http://www.go-pear.org/manual/ja/html/package.php.phpunit.html

Do You PHP? - PhpUnit - 最強のユニットテスト自動化ツール
http://www.doyouphp.jp/tips/tips_phpunit.shtml

PEAR hacks - PHPUnitの使い方
http://www.aglabo.com/agl/proevo/PHP/PEAR/phpunit-howto.html

PhotoCabi-diary - 2004-11-18 - PHPUnitの使い方
http://www.photocabi.net/mt/archives/000049.html

2006-11-30 Thu

Smartyを使った開発でデバッグを行う方法

- Summary
Smartyを使った開発でデバッグを行う方法.

- 常にデバッギングコンソールをポップアップ表示

$smarty->debugging = true;


- 常にデバッギングコンソールをHTML内に表示
$smarty->debugging = true;
$smarty->assign('_smarty_debug_output', 'html');


- URL に SMARTY_DEBUG が含まれる場合にデバッギングコンソールを表示
$smarty->debugging_ctrl = 'URL';


- テンプレート変数 debug を利用してポップアップ表示


- テンプレート変数 debug を利用してHTML内に表示
{debug output='html'}


- debug_print_var 修正子を利用して,割り当てられた変数を表示
{$foo|@debug_print_var}


- debug_print_var 修正子を利用して,割り当てられた変数を表示
インデント1単位,100文字まで表示.
インデント1単位は半角スペース2文字分.
{$foo|@debug_print_var:2:100}


- Reference
cl.pocari.org - Smarty を使った開発でデバッグを行う 4 つの方法
http://cl.pocari.org/2006-11-29-1.html

Smarty - $debugging
http://smarty.php.net/manual/en/variable.debugging.php

Smarty - $debugging_ctrl
http://smarty.php.net/manual/en/variable.debugging.ctrl.php

Smarty - {debug}
http://smarty.php.net/manual/en/language.function.debug.php

$debugging
$debugging_ctrl
{debug}

2006-11-24 Fri

PearのServices_JSONを使ってPHPの変数を簡単にJSON形式にする

- Summary
日本語を使う場合はUTF-8の変数を渡す必要がある.

require_once('Services/JSON.php');
 
$json = new Services_JSON();
$obj = array(
    'id'   => array(
       'foo',
       'bar',
       array('aa' => 'bb')
       ),
       'foobar' => $string,
       'a'   => 123 ,
       'b'   => true
);
$js = $json->encode($obj);
echo $js;


- Reference
phpspot開発日誌 - PearのServices_JSONを使ってPHPの変数を簡単にJSON形式にするサンプル
http://phpspot.org/blog/archives/2006/11/pearservices_js.html