9/7(水)と9/8(木)のmemo

一日飛ばすと結構たまるから毎日更新しなければ。
reCAPTCHAうまく導入できなく、停滞気味。
明日はアプローチ変えてみるけど、明日のうちに機能はworkさせたい。
そもそもユーザビリティ下がるからどうなのというところだけど。
設置されていたCAPTCHAが突破されているなら致したかないのか??
バランスが難しい。バランスってなんだろう。

最近のテーマ
『非効率で不器用な人間だからこそ「量」で勝負する。』
そもそも努力が足りないから。まず量でいこう。

reCAPTCHAについて

reCAPTCHAコード読解

<?php
//サーバーの通信の定義
define("RECAPTCHA_API_SERVER", "http://www.google.com/recaptcha/api");
//https通信の定義
define("RECAPTCHA_API_SECURE_SERVER", "https://www.google.com/recaptcha/api");
//確認サーバーの定義
define("RECAPTCHA_VERIFY_SERVER", "www.google.com");

//クエリ文字列形式に与えられたデータをエンコードする。
//パラメーター:$data エンコードされる要素の文字配列
//返り値:エンコードされたリクエスト

function _recaptcha_qsencode ($data) {
        $req = "";
        foreach ( $data as $key => $value )
                $req .= $key . '=' . urlencode( stripslashes($value) ) . '&';

        // Cut the last '&'
        $req=substr($req,0,strlen($req)-1);
  //$reqの0(始めの文字)から最後の文字($reqの文字列の長さ-1によって)を抜いた分を抜き出す
        return $req;
}

//PHP関数memo
//urlencode ― 文字列を URL エンコードする
//stripslashes ― クォートされた文字列のクォート部分を取り除く
//substr― 文字列の一部分を返す
//strlen― 文字列の長さを得る


//HTTP POSTをreCAPTCHAサーバーに送信する。
//パラメーター:$host(URI)、$path、$data、$port(ポート番号:80番)
//返り値:配列

function _recaptcha_http_post($host, $path, $data, $port = 80) {

        $req = _recaptcha_qsencode ($data);

        $http_request  = "POST $path HTTP/1.0\r\n";
        $http_request .= "Host: $host\r\n";
        $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n";
        $http_request .= "Content-Length: " . strlen($req) . "\r\n";
        $http_request .= "User-Agent: reCAPTCHA/PHP\r\n";
        $http_request .= "\r\n";
        $http_request .= $req;

        $response = '';
        if( false == ( $fs = @fsockopen($host, $port, $errno, $errstr, 10) ) ) {
                die ('Could not open socket');
        }

        fwrite($fs, $http_request);

        while ( !feof($fs) )
                $response .= fgets($fs, 1160); // One TCP-IP packet
        fclose($fs);
        $response = explode("\r\n\r\n", $response, 2);

        return $response;
}

//PHP関数memo
//fsockopen:― インターネット接続もしくはUnix ドメインソケット接続をオープンする
//fwrite ― バイナリセーフ(正しく扱うことが出来る関数)なファイル書き込み処理
//feof ― ファイルポインタがファイル終端に達しているかどうか調べる
//fgets ― ファイルポインタから 1 行取得する
//fclose ― オープンされたファイルポインタをクローズする
//explode ― 文字列を文字列により分割する

//ファイルポインタは、有効なファイルポインタである必要があり、
//fopen() または fsockopen() で正常にオープンされた(そしてまだ fclose() でクローズされていない)ファイルを指している必要がある。


//解読するためのHTMLを得る関数
//ブラウザから呼ばれ、結果としてreCAPTCHAHTMLWidgetとなる。
//呼ばれたものはフォーム内に埋め込まれる。

//パラメーター
//$pubkey reCAPTCHAのための公開鍵
//$error reCAPTCHAによって与えられたエラー(オプションでデフォルトはnull)
//$use_ssl sslを用いてリクエストするなら(オプションでデフォルトはfalse)
//返り値:ユーザーのフォームに埋めこまれたHTML

function recaptcha_get_html ($pubkey, $error = null, $use_ssl = false)
{
        if ($pubkey == null || $pubkey == '') {
                die ("To use reCAPTCHA you must get an API key from <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>");
        }

        if ($use_ssl) {
                $server = RECAPTCHA_API_SECURE_SERVER;
        } else {
                $server = RECAPTCHA_API_SERVER;
        }

        $errorpart = "";
        if ($error) {
           $errorpart = "&amp;error=" . $error;
        }
        return '<script type="text/javascript" src="'. $server . '/challenge?k=' . $pubkey . $errorpart . '"></script>

        <noscript>
                <iframe src="'. $server . '/noscript?k=' . $pubkey . $errorpart . '" height="300" width="500" frameborder="0"></iframe><br/>
                <textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
                <input type="hidden" name="recaptcha_response_field" value="manual_challenge"/>
        </noscript>';
}


//ReCaptchaResponsはrecaptcha_check_answer関数から返されたもの。
 
class ReCaptchaResponse {
        var $is_valid;
        var $error;
}


//recaptcha_check_answer関数
//ユーザーの推測が正しかった場合、確認機能としてHTTP POSTが呼ばれる。

//パラメーター
//$privkey 秘密鍵
//$remoteip reCAPTCHAを解いたユーザーのIPアドレス
//$challenge フォームの中のrecaptcha_challenge_fieldに記入された内容 
//$respose フォームの中のrecaptcha_response_fieldに記入された内容 
//$extra_params サーバーへの送信のために加えて確認する配列


function recaptcha_check_answer ($privkey, $remoteip, $challenge, $response, $extra_params = array())
{
  //秘密鍵がnulか空であったらメッセージ。
        if ($privkey == null || $privkey == '') {
                die ("To use reCAPTCHA you must get an API key from <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>");
        }

  //ユーザーのIPアドレスがnullか空だったら
        if ($remoteip == null || $remoteip == '') {
                die ("For security reasons, you must pass the remote ip to reCAPTCHA");
        }



        //discard spam submissions(スパム投稿を破棄する)
  //フォームの値が空だったり、、文字列の長さが0だった時
        if ($challenge == null || strlen($challenge) == 0 || $response == null || strlen($response) == 0) {
                $recaptcha_response = new ReCaptchaResponse();
                $recaptcha_response->is_valid = false;
                $recaptcha_response->error = 'incorrect-captcha-sol';
                return $recaptcha_response;
        }

        $response = _recaptcha_http_post (RECAPTCHA_VERIFY_SERVER, "/recaptcha/api/verify",
                                          array (
                                                 'privatekey' => $privkey,
                                                 'remoteip' => $remoteip,
                                                 'challenge' => $challenge,
                                                 'response' => $response
                                                 ) + $extra_params
                                          );

        $answers = explode ("\n", $response [1]);
        $recaptcha_response = new ReCaptchaResponse();

        if (trim ($answers [0]) == 'true') {
                $recaptcha_response->is_valid = true;
        }
        else {
                $recaptcha_response->is_valid = false;
                $recaptcha_response->error = $answers [1];
        }
        return $recaptcha_response;

}


//ユーザーがreCAPTCHAにサインアップできるようにURLを得る。
//もしアプリケーションにどこかキーが入っている設定ページがあるなら、この機能が使われているリンクを供給すべきだ。

function recaptcha_get_signup_url ($domain = null, $appname = null) {
        return "https://www.google.com/recaptcha/admin/create?" .  _recaptcha_qsencode (array ('domains' => $domain, 'app' => $appname));
}

function _recaptcha_aes_pad($val) {
        $block_size = 16;
        $numpad = $block_size - (strlen ($val) % $block_size);
        return str_pad($val, strlen ($val) + $numpad, chr($numpad));
}

//PHP関数memo
//str_pad ― 文字列を固定長の他の文字列で埋める
//chr ― 特定の文字を返す
?>

PHPについて

requireとinclude

require( )とinclude( )との違いは、require( )が処理中に1回だけ読み込まれると言う点

1)require系はファイルを読み込めなければ必ずエラーで停止する
2)include系はファイルを読み込めなければ必ず警告を(内部レベルでは)出力する。あとfor文などの変数型ファイル読み込みに使える。

どうしてもファイルが存在していてもしていなくても読み込みたければfile_exists()などでファイルの存在を調べてrequireすればいいと思う。
ob_start ― 出力のバッファリングを有効にする
バッファリング:複数の機器やソフトウェアの間でデータをやり取りするときに、処理速度や転送速度の差を補うためにデータを専用に設けられた記憶領域一時的に保存しておくこと

●public
どのクラスからもアクセスできるということ
●static
staticとは固定という意味。
クラス特有の値やメソッドということ。
●void
戻り値なし
詳しくサンプル
http://www.searchman.info/tips/2070.html

ob_gzhandler ― 出力バッファを gzip 圧縮するための ob_start コールバック関数
strpos ― 文字列が最初に現れる場所を見つける
ctype_alpha ― 英字かどうかを調べる
ctype_digit ― 数字かどうかを調べる

apacheについて

アクセス権変更のコマンドの書式
chmod [オプション] [アクセス権の指定] [ファイル/ディレクトリ名]
ex.700=自分だけ読み書き可能、他人は一切見れない

ファイル/フォルダの所有者の変更コマンドは、次のような構文となる。
chown [オプション] [ユーザ名] [ファイル/ディレクトリ名]

English

I'm sorry in such a short notice but〜
急な話で悪いんだけど
→これは結構便利だから早速今日使った。

Security関係

PHP と Web アプリケーションのセキュリティについてのメモ」を読んで

『aaa@bbb.com』というメアドを
『&#97;&#97;&#97;&#64;&#98;&#98;&#98;&#46;&#99;&#111;&#109;』とすることをエンティティ変換という。
セキュリティ識別子 (SID; Security Identifier)

セッション関連の処理で注意すべきクロスサイトスクリプティング問題に関して
strip_tags() ではダブルコーテーションが削除されない。
この問題は、PHP 4.3.2 で修正。
結果的にstrip_tags()はやめて、htmlspecialchars()にすべきということ。

文字コードUTF-7 を使用したクロスサイトスクリプティングに関して
htmlentities — 適用可能な文字を全て HTML エンティティに変換する

ちょいmemo

「ソケット」というのはIPアドレスとPort番号を一組にしたもの。
svn revert ファイル名:svn内のファイルをサーバーのファイルに上書き
PKI(Public Key Infrastructure)は公開鍵暗号基盤と訳され、所有者と公開鍵の対応付けをするのに必要な方式、システム、プロトコル及びポリシの集合によって実現される。
リファクタリング (refactoring) とはコンピュータプログラミングにおいて、プログラムの外部から見た動作を変えずにソースコードの内部構造を整理すること。

http://www.amazon.co.jp/dp/4798020826/?tag=hatena_st1-22&ascsubtag=d-ap51
サイト
http://jsdo.it/event/html5cat/2011/summer/