上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。



ブログを移転します。 FC2ブログ → はてなブログ リンク集から飛んでください。
スポンサーサイト


半角英数字がどちらも登場して且つそれら8文字以上で構成されているか調べる正規表現

/(?!\A[a-z]*+\z)(?!\A\d*+\z)\A[a-z\d]{8,}+\z/i




こちらに移転しました。


<?php
 
// HTML特殊文字エスケープ用
function h($input) {
    return htmlspecialchars($input, ENT_QUOTES, 'UTF-8');
}

// 変数$dateを初期化
$date = '';

try {
    
    // 入力項目チェック
    switch (true) {
        // フォーム送信が行われていないとき
        case !isset($_POST['date']):
            throw new Exception('年齢と世代を判定します。');
        // 不正に配列で送信されてきたとき
        case !is_string($_POST['date']):
            throw new Exception('不正なリクエストです。');
    }
    
    // 日付フォーマットを2通り受け取る
    // (前後にスペース等が含まれている場合も許可)
    switch (true) {
        // 2013-01-01
        // 2013年1月1日
        // 2013/01/01
        // 2013.01.01
        // 13/01/01
        // など
        case preg_match(
            '/\A[^\d]*+(\d++)[^\d]++(\d++)[^\d]++(\d++)[^\d]*+\z/',
            $date = $_POST['date'],
            $m
        ):
        // 20130101
        case preg_match(
            '/\A[^\d]*+(\d{4})(\d{2})(\d{2})[^\d]*+\z/',
            $date,
            $m
        ):
            break;
        // それ以外
        default:
            throw new Exception('フォーマットが不正です。');
    }
    
    // 実際にそれが日付として有効かどうかも調べる
    switch (true) {
        // タイムスタンプに一度変換する
        // (うるう年や年2桁フォーマットを考慮した処理はここで行われる)
        case ($time = mktime(0, 0, 0, $m[2], $m[3], $m[1])) === false:
        // 未来は不正とする
        case $time > $_SERVER['REQUEST_TIME']:
            throw new Exception('日付が不正です。');
    }
    
    // 年齢算出
    $d1 = date('Ymd', $time);
    $d2 = date('Ymd', $_SERVER['REQUEST_TIME']);
    $old = (int)(($d2 - $d1) / 10000);
    
    // 世代算出
    $gen = (int)($old / 10) * 10 . '代';
    if ($gen < 10 || $gen > 70) {
        $gen = 'その他';
    }
    
    // 結果をセット
    $message = sprintf(
        '%s生まれのあなたは%s歳(%s)です。',
        date('Y年n月j日', $time),
        $old,
        $gen
    );
    
} catch (Exception $e) {
    
    // 例外メッセージをセット
    $message = $e->getMessage();
    
}

// ヘッダー送信
header('Content-Type: application/xhtml+xml; charset=utf-8');

?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja">
  <head>
    <title>年齢・世代判定</title>
  </head>
  <body>
    <p><?=h($message)?></p>
    <form method="post" action="">
      <p>
        生年月日:
        <input type="text" name="date" value="<?=h($date)?>" />
        <input type="submit" value="送信" />
      </p>
    </form>
  </body>
</html>



<?php

class MultiRequest {
    
    const TIMEOUT = 10;
    
    private $mh;
    private $ch = array();
    private $result = array();
    
    public static function get(array $urls) {
        return self::request($urls);
    }
    
    public static function post(array $urls, array $postfields) {
        if (
            array_diff_key($urls, $postfields) ||
            array_diff_key($postfields, $urls)
        ) {
            throw new InvalidArgumentException(
                'each $urls and $postfiels must have same keys'
            );
        }
        return self::request($urls, $postfields);
    }
    
    private static function request(array $urls, $postfields = null) {
        $self = new self;
        foreach ($urls as $key => $url) {
            if ($postfields !== null) {
                $self->add($key, $url, $postfields[$key]);
            } else {
                $self->add($key, $url);
            }
        }
        $self->execute();
        return $self->getResult();
    }
    
    private function __construct() {
        $this->mh = curl_multi_init();
    }
    
    private function __destruct() {
        foreach ($this->ch as $ch) {
            curl_multi_remove_handle($this->mh, $ch);
            curl_close($ch);
        }
        curl_multi_close($this->mh);
    }
    
    private function add($key, $url, $postfields = null) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, self::TIMEOUT);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, self::TIMEOUT);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_ENCODING, 'gzip');
        curl_setopt($ch, CURLINFO_HEADER_OUT, true);
        if ($postfields !== null) {
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
        }
        curl_multi_add_handle($this->mh, $ch);
        $this->ch[$key] = $ch;
    }
    
    private function execute() {
        do {
            $stat = curl_multi_exec($this->mh, $running);
        } while ($stat === CURLM_CALL_MULTI_PERFORM);
        do {
            curl_multi_select($this->mh, self::TIMEOUT);
            do {
                $stat = curl_multi_exec($this->mh, $running);
            } while ($stat === CURLM_CALL_MULTI_PERFORM);
        } while ($running);
    }
    
    private function getResult() {
        $result = array();
        foreach ($this->ch as $key => $ch) {
            $result[$key] = 
                  array('content' => curl_multi_getcontent($ch))
                + curl_getinfo($ch)
            ;
        }
        return $result;
    }
    
}



PHP Dream

「検索システムを作る」

http://php.dori-mu.net/search.html


率直に思ったことをそのまま述べさせていただきます。
自重は一切しません。


早くサイト閉鎖しろ。


2007年から放置されててクソ古い情報しかないのにそれを鵜呑みにする初心者がたくさんいるせいで大変なことになっています。BBSもスパム投稿で荒れ放題、まともにコンタクト先も記されておりません。特にタイトルで述べた 「検索システムを作る」 に関する質問を今まで何件か見てきました。 ここに私なりに、今(2013/9/4)ならどう書くべきかを著します。




結論から述べると、関連性は薄いだろう。

根拠

  • 日本だけではなく、世界で凍結騒ぎが起こっていること。
    【注意】ツイッターアカウントが突然凍結される騒ぎが世界レベルで発生中!…
  • 同一IPからの特定アカウントに対する連続スパム報告は、1回として見なされること。
  • 上記のIP制限を回避するためのツール、「ぶろったー for Windows」があまり浸透していなさそうに感じられること。常駐させておく必要があり、余程ぶろったーに思い入れのある人以外で使う人は少ないと思われる。(これは憶測に過ぎないが)

以上の理由による。
確証は得られないが、おおよそこの推測は間違ってはいないだろう。
勘違いしてほしくないのが、だからといってぶろったーを正当化してはいけないということだ。散々今まで言われてきたが、このツール、スパムアカウントやパクリBOTを潰すためだけでなく、一般のユーザーに対する憂さ晴らしの手段として容易に使用され得るのが一番の問題である。既に上で述べたとおり、「ぶろったー for Windows」は非常に危険なツールであり、もしこの使用が広まればTwitterは地獄絵図となるだろう。

パクリBOTを潰すためならばこのようなサービスがすでにあるので、わざわざぶろったーを使うには至らない。

同じTwitterを利用したWebサービス運営者として思うことを。

このように身勝手すぎるアプリケーションの存在と、作者の思想は断じて許されるものであってはならない。


この方が作者。

いや、既にぶろったーのコンシューマーキーが凍結された時点でTwitterからの警告だろ。








最後に・・・
「自分には関係ないし・・・」で済ませる方、「明日は我が身」という言葉はご存じだろうか。




PHPの配列をJavaScriptで使用するベストプラクティスは?
http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q10110000690

知恵袋でこんな質問があったので回答用にコーディングしてみました。

参考にさせていただいたページ

  • PHP5.2以前の環境でのjson_encode
    http://d.hatena.ne.jp/ksy_dev/20101031/p1
    ここのコードをパクるより洗練する形を取りました。
    再現度とパフォーマンスがかなり向上していると思います。
  • PHPでユニコードエスケープ(unicode_encode, unicode_decode代替)
    http://d.hatena.ne.jp/iizukaw/20090422
    エンティティ変換の部分ではほとんど丸コピってぐらい使わせていただきました。
    非常に美しいコードだと思います。
json_encode()
<?php


if (!function_exists('json_encode')) {
    
    function json_encode($it) {
        if (!($assoc = is_object($it)) && !is_array($it)) {
            return _js_enc_value($it);
        }
        $i = 0;
        $it = (array)$it;
        if (!$assoc) {
            foreach ($it as $k => $v) {
                if ($k !== $i) {
                    $assoc = true;
                    break;
                }
                $i++;
            }
        }
        $data = array();
        foreach ($it as $k => $v) {
            $v = _js_enc_value($v);
            if ($assoc) {
                $k = _js_enc_value((string)$k);
                $data[] = $k . ':' . $v;
            } else {
                $data[] = $v;
            }
        }
        if ($assoc) {
            $bl = '{';
            $br = '}';
        } else {
            $bl = '[';
            $br = ']';
        }
        return $bl . implode(',', $data) . $br;
    }

    function _js_enc_value($value) {
        switch (true) {
            case is_array($value):
            case is_object($value):
                return json_encode($value);
            case $value === null:
            case is_resource($value):
                return 'null';
            case is_bool($value): 
                return $value ? 'true' : 'false';
            case is_string($value):
                return '"' . _js_uc_esc($value) . '"';
            default:
                return $value;   
        }
    }
    
    function _js_uc_esc($value) {
        $pattern = "@[\x08-\x0a\x0c\x0d\\\\\"/]|([^\x08-\x0a\x0c\x0d\x20-\x7f\\\\\"/])++@u";
        return preg_replace_callback($pattern, '_js_uc_esc_cb', $value);
    }
 
    function _js_uc_esc_cb($matches) {
        switch (true) {
            case isset($matches[1]):
                $char = mb_convert_encoding($matches[0], 'UTF-16', 'UTF-8');
                $str = '';
                $len = strlen($char);
                for ($i = 0; $i < $len; $i += 2) {
                    $str .= sprintf('\\u%02x%02x',
                        ord($char[$i]),
                        ord($char[$i + 1])
                    );
                }
                return $str;
            default:
                return addcslashes($matches[0], "\x08\x09\x0a\x0c\x0d\\\"/");
        }
    }
 
}


動作テスト: http://3v4l.org/YBg06
  • mb_check_encoding関数のバリデーションはクソ仕様なのでアテにならない。よって今回関数側で不正エンコーディングチェックをするのは割愛。
  • PHP5.5からは変換できないリソース型が子要素に来た時点で全体がfalseにされる。今回は5.4以下仕様にしてみた。
  • 5.0.05.1.6にはオブジェクトをforeach構文でイテレートできないというバグがあるので配列キャストを入れてみた。
  • 5.2.05.2.1には空文字キーの配列要素が存在することが出来ないというバグあるが、これは言語構造上どうしようもないのでスルー。

まともにPHP使えるようになったのって、PHP5.4.1以降だと思う。
それより前のバージョンはバグだのセキュリティホールだのもう目に余る光景。




【パソコン操作もままならない初心者向け】

いきなりはじめるPHP ~ワクワク・ドキドキの入門教室~

Amazonでちら見してみた感じ、とりあえず、めちゃくちゃ丁寧
HTMLの書き方からここまで説明してくれる参考書は他に無さそう。
これで挫折する人はいないだろうという。
一応MySQLとの接続も取り上げられています。

【HTMLぐらいは書けるけどプログラミング未経験な人向け】

ゼロからわかる PHP超入門

この本は私持ってます。
内容は上の「いきなり始めるPHP」の超初心者向けの部分を削った感じ。
だけかと思いきや、MySQLも削られてるので、ちょっと削りすぎかな?
でも基礎部分をサクッと読み終えて、2冊目の "良書" に進みたい、って考え方ならむしろこの本が良いと思う。

【C言語とかBASICはやったことあるけどPHPは完全に未経験な人向け】

よくわかるPHPの教科書

これは持ってる人多いですね。
内容的には上の「ゼロから始める PHP超入門」の削りすぎな部分を補填した感じのようです。
ただ、誤植が多かったり、この本のことで知恵袋のPHPカテゴリで質問してくる人が(私のポリシー的に)「あり得ないコード」を書いてきたりするので、そういう意味ではあまりオススメは出来ません。PHP超入門の方がいいかも。
酷いコードが書かれていることを知ったのでお勧め撤回します(笑

【2冊目が欲しい初心者向け】
【サンプルコードを自分で応用したりしてちょっとぐらいは書ける人向け】
【そろそろPHP「超初心者」ではないなと自覚できる人向け】
【PHP(自称)中級者向け】
【フレームワークだけ未経験なんです><という人向け】
【初心者だけど間違ったこと書いてないクオリティの高い本が欲しい人向け】

パーフェクトPHP

↑超オススメ!!!

この本は先日購入しました。
若干私のポリシーに反する書き方も見受けられますが、
本質的な内容に関してはまさに「パーフェクト!!」と大絶賛したくなるクオリティです。

章構成

  1. PHP概論
    OS別のインストール方法など。CLIについても触れています。
  2. PHPの基本
    構文・変数・定数・エラー・例外などについて、細かいところまで触れ、次章以降の展開に繋げています。
  3. 型と演算子
    ほぼ "漏れなく" といっていいぐらい完璧にあらゆるものが分かりやすく列挙されています。
  4. 制御構造と関数
    gotoまで書いてくれてる本とかなかなか無さそうwww
  5. クラスとオブジェクト
    継承や抽象クラス、遅延的束縛、名前空間など、一般的な参考書では削られやすい内容についても漏れが無いです。
    オブジェクトがどう管理されるかについて、C言語レベルでの挙動までとっても正確に書かれています。
  6. Webアプリケーション入門
    ここからMySQLなども交えて実際にアプリ作っていきます。しかし、現在は非推奨のmysql関数が使われているのだけが唯一の欠点です。
    ともあれ、次の章ではその代替手段となるPDOについて触れてくれているのでまぁいいかな、って。
  7. フレームワークによる効率的な開発
    フレームワークごちゃごちゃしてて気持ち悪いと思ってましたが、この章を読んでからそういう意識がかなり変わりました。
    フレームワークを自作から入らせるのは素晴らしい視点だと思いました。この本のメインディッシュです。
  8. ミニブログアプリケーション開発
    ↑の続き。自作したフレームワークをここで実際に利用していきます。
  9. PHPで作るWebアプリケーションのセキュリティ(前半)
    「セキュリティとか大丈夫wwww」と思ってたら意外と目から鱗な内容もありました。
    相変わらず抜け目ないですこの本。
  10. PHPで作るWebアプリケーションのセキュリティ(後半)
    ↑の続き。
  11. 実践オブジェクト指向
    フレームワーク作成の章で少し基礎部分に対する説明が荒くなりますが、それをここでカバーしている感じです。
    確かに具体例展開中に一気に説明しすぎるよりはこうやって後で補填する方がいいかも。
  12. レシピことはじめ
    マニュアルの見方とか。
  13. 標準機能
    利用頻度の高い関数をまとめてくれてある章。
    初心者から中級者にステップアップしたい人にとっては非常にありがたい章だと思います。
  14. ライブラリとフォーマット
    標準組み込みクラス・外部ライブラリ(PEARなど)の使い方について触れてます。
ぜひこれは持っておきましょう!!!非常に頼もしい1冊です!!!

【PHP(自称)上級者を目指している人向け】
【既にプロとして活動している人向け】

PHP5徹底攻略 エキスパート編

「パーフェクトPHP」でも物足りないような上級者用。
SOAP・PDFなどわりとマイナーな機能の取り扱い、チューニングなどいろいろ触れているようですが、 この本の一番の目玉は「エクステンションの作成」だと思います。
自分でPHP内部の関数を実装できるんです。C言語を記述して。
これは今後私も買っておきたい1冊ではありますね。




この記事はQiitaに移転しました


上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。