9 30

[php]curlでダイジェスト認証(Digest-Auth)を通過する

Tag: phpuechoco @ 22 : 13 : 17

phpスクリプトでダイジェスト認証(Digest-Auth)を通過する方法を調べていたのですが、どうやらcurlライブラリを用いるしか方法が見当たりません。その他の方法があれば教えてください。

で本題のダイジェスト認証の通過ですが、ネットで調べて2件だけありました。
Perl Tips | PHP で、ダイジェスト認証(Digest Auth)をする HTTP クライアント
PHPでダイジェスト認証(curl) - ユーウツな雨がふりつづいても雪がハートを曇らせてもドアの中で待っていた君に魔法をかけたいのさ

とにかくまずは CURL が PHP で動けば、あとはプロトコルとして HTTP、HTTPS(SSL/TLS)、FTP、Telnet、LDAP プロトコルでアクセスするクライアントを作れるようだ。 CURL では HTTP だと、GET、POST、PUT、FTP アップロード、フォームからのアップロード、Proxy、cookie、ユーザ名とパスワードによる基本認証/ダイジェスト認証、HTTP(または HTTPS)の認証…と、フルサポートするようだ。

php:
  1. $ch = curl_init();
  2. curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
  3. curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
  4. curl_setopt($ch, CURLOPT_URL, $url);
  5. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  6. $str = curl_exec($ch);
  7. curl_close($ch);

curlのいいところは、「HTTPS+ダイジェスト認証」みたいな際どいURLなんかにもアクセスできちゃうこと。しかも認証されていないhttpsにアクセスするためのオプションもちゃんとある。以下がそのオプション。

php:
  1. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  2. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

これでやりたいことができるようになった!うーん・・・でも世の中的にはBasic認証の方が一般的ですよね。HTTPS+Digest-Authってレアかなぁ。。。


9 27

[Let's note]2008年冬モデルでCF-F8登場、T8とR8はメモリ最大3GB

Tag: 情報収集uechoco @ 08 : 48 : 06

パソコン(個人向け)| Let'snote(レッツノート モバイルパソコン) | Panasonic
松下電器、ビジネスノート「Let'snote」新モデル発表会 | パソコン | マイコミジャーナル
松下、Let'snoteシリーズに14.1型ワイド液晶搭載の新モデル投入 | パソコン | マイコミジャーナル

2008年冬モデルで"8"シリーズになりましたね!

注目は、新シリーズCF-F8の登場。なんと!ダサい取っ手が付いてるwww そこまでするなら収納ポケットとか、つけちゃって、カバンいらずのLet's noteとかにしてくれYo!(ぉぃ

今回のモデルでYシリーズ以外はCentrino 2 プロセッサー・テクノロジー対応で、無線がIEEE 802.11 ドラフトnになってますね。そのうち省電力が進んでバッテリー駆動時間も伸びそうですね。あと、DDR3メモリに対応してくれればでさらに消費電力ダウンかな?

そういえば、CF-T8とCF-R8はメモリが最大3GBに増設可能だとか。ようやく3GBですか。CF-W8は最大4GBにしてくれればいいのに。

感想としては、やっぱり富士通のLOOX Rシリーズの2008年秋冬モデルが、1歩どころか、5歩くらいリードしてるかな。完全浮気しそうだゎw


9 24

[php]文字列の各文字の間に別の文字列を挿入するスクリプト

Tag: phpuechoco @ 00 : 05 : 04

文章を書いていた時に、たまたま「1と2と3と5と6」と言う文字列を順番どおりに書いて、入力切り替えのかったるさを実感しました。ふと考えてみると。「12356」を先に書いてから、あとから間に「と」を入れてくれるとスマートな気がして、でもphpでどうやって書くんだろうっていう、変な妄想にふけりました。

妄想の結果:

php:
  1. $insert = 'と';
  2. $str = '12356';
  3.  
  4. $len = strlen($str);
  5. for ($i = 0; $i <$len; $i++) {
  6.     echo ($i> 0) ? $insert . $str[$i] : $str[$i];
  7. }

もう少し、スマートに書けるんじゃないかと思ったけど、これで満足・・・・と思いきや、$strがマルチバイトだと動かなそうな気がした。で、第2版がこちら

php:
  1. $insert = 'to';
  2. $str = 'あいうえお';
  3.  
  4. mb_internal_encoding('UTF-8'); // 環境に合わせて
  5. $len = mb_strlen($str);
  6. for ($i = 0; $i <$len; $i++) {
  7.     echo (($i> 0) ? $insert : '') . mb_substr($str, $i, 1);
  8. }

まーこれでいいかなぁー。自分の要望は満たしてるし。でもphpならもっとスマートにできる関数があると思うんだけどな。


9 21

[symfony]ログイン認証バリデータ(データベース接続)のサンプル

Tag: phpuechoco @ 20 : 42 : 29

symfony1.1で、メールアドレスとパスワードによるログインフォームを作りたい。

ログインフォーム

ログインフォーム

メンバー情報などが記録されたMemberテーブルは以下の仕様

TEXT:
  1. propel:
  2. member:
  3. _attributes: { idMethod: native }
  4. id: { type: INTEGER, required: true, autoIncrement: true, primaryKey: true }
  5. name: { type: VARCHAR, size: '255', required: true, default: '' }
  6. mail_pc: { type: VARCHAR, size: '255', required: true, default: '' }
  7. password: { type: VARCHAR, size: '255', required: true, default: '' }
  8. created_at: { type: TIMESTAMP }
  9. updated_at: { type: TIMESTAMP }
  10. last_logined_at: { type: TIMESTAMP }
  11. is_admin: { type: TINYINT, default: '0' }
  12. enabled: { type: TINYINT, required: true, default: '1' }

ログインフォームに必要なバリデータは、個々の項目(mail_pc、password)のバリデートと、データベースへの問い合わせの2つ。個々の項目のバリデートはバリデータを使えばすぐにできそう。以下のような感じ。

php:
  1. class LoginForm extends sfForm
  2. {
  3. public function configure()
  4. {
  5. $this-&gt;setWidgets(array(
  6. 'mail_pc'  =&gt; new sfWidgetFormInput(array(), array('size' =&gt; 50)),
  7. 'password' =&gt; new sfWidgetFormInputPassword(array(), array('size' =&gt; 32)),
  8. ));
  9.  
  10. $this-&gt;widgetSchema-&gt;setLabels(array(
  11. 'mail_pc'  =&gt; 'PCメールアドレス',
  12. 'password' =&gt; 'パスワード',
  13. ));
  14.  
  15. $this-&gt;widgetSchema-&gt;setNameFormat('login[%s]');
  16.  
  17. $this-&gt;setValidators(array(
  18. 'mail_pc'  =&gt; new sfValidatorEmail(
  19. 'required' =&gt; 'メールアドレスを入力してください。',
  20. 'invalid'  =&gt; 'メールアドレスが正しくありません。'
  21. )
  22. ),
  23. 'password' =&gt; new sfValidatorString(
  24. array('min_length' =&gt; 6, 'max_length' =&gt; 64),
  25. 'required'   =&gt; 'パスワードを入力してください。',
  26. 'min_length' =&gt; 'パスワードは%min_length%文字以上です。',
  27. 'max_length' =&gt; 'パスワードは%max_length%文字以下です。',
  28. )
  29. )
  30. ));
  31. }
  32.  
  33. }

エラー処理とかもバリデータが一括で請け負ってくれるので、データベースへの問い合わせもバリデータにすればすっきりすると思って、作ろうと思ったけど、ネット上に資料が少ない。どうやっていいかよくわからない。

とりあえず、複数項目のバリデートだから、validatorSchemaのsetPostValidator()に登録するんじゃないかと気づく。こんな感じでsfValidatorSchemaLoginクラスを作ってみた。

php:
  1. /**
  2. * sfValidatorSchemaLogin
  3. *
  4. * @package    Travi
  5. * @subpackage validator
  6. */
  7. class sfValidatorSchemaLogin extends sfValidatorBase
  8. {
  9. /**
  10. * @see sfValidatorBase
  11. */
  12. protected function doClean($values)
  13. {
  14. if ($values['mail_pc'] != '' &amp;&amp; $values['password'] != '') {
  15. // 両パラメータが与えられたときだけ実行
  16. $encrypted_password = myUtil::encrypt($values['password']);
  17. if (MemberPeer::isValidUser($values['mail_pc'], $encrypted_password)) {
  18. return $values;
  19. } else {
  20. throw new sfValidatorError($this, 'invalid', array());
  21. }
  22. }
  23. return $values;
  24. }
  25. }

このクラスのミソは、必要なパラメータ(メールアドレスとパスワード)がそろったときだけ、データベースに問い合わせること。なぜかというと、メールアドレスかパスワードのバリデータが成功した時点でデータベースの問い合わせをした方が効率がいいので。

最後に、LoginFormのPostValidatorを登録

php:
  1. $this-&gt;validatorSchema-&gt;setPostValidator(
  2. new sfValidatorSchemaLogin(
  3. 'invalid'  =&gt; 'メールアドレスかパスワードが間違っています。'
  4. )
  5. )
  6. );

意外と簡単にいけたけど、もっとスマートな方法ないかなぁ。。。Propel系の標準Validatorがいまいちよくわからないんだな。


9 21

[symfony]Fatal error: Class ‘BaseFormPropel’ not found

Tag: phpuechoco @ 18 : 53 : 46

(関連記事:[symfony]Class ‘BaseFormPropel’ not foundエラー解決

symfony 1.1系列が出てるので、sandboxを拡張してsfFormの練習がてらアプリを作っているのですが、symfony 1.1.1や1.1.2で、以下のようなエラーが出ました。

php:
  1. [?php /** * Project form base class. * * @package form * @version SVN: $Id: sfPropelFormBaseTemplate.php 6174 2007-11-27 06:22:40Z fabien $ */
  2. abstract class BaseFormPropel extends sfFormPropel { public function setup() { } }
  3. Fatal error: Class 'BaseFormPropel' not found in /path/to/symfony/lib/form/base/BaseMemberForm.class.php on line 10

状況的には、symfonyコマンドのpropel:build-formsで作成したフォームを使おうとすると、BaseFormPropelクラスがないって言って、上のようなエラー画面になってしまう。

不自然なのは、phpタグが大括弧で始まっていること。

プロジェクト内を検索してみたら、

TEXT:
  1. /lib/symfony/plugins/sfPropelPlugin/data/generator/sfPropelForm/default/template/sfPropelFormBaseTemplate.php

に確かに大括弧で始まる同じデータがあった。

なんでこのファイルをロードするんだろう。。。

解決策1

とりあえず、自分のやる気をそがれるのが嫌だから、暫定措置として、/lib/form/base/BaseXXXXForm.class.phpのextendsしているクラスをBaseFormPropelからsfFormPropelに変更。簡単に言うと、BaseFormPropelっていう中間のクラスを抜いただけ。とりあえず、それほど大きいアプリじゃないから、このままでいいや。

解決策2

思いつきで、クラス名とファイル名を変えてあげればいいかなっと思って、/lib/form/base/BaseXXXXForm.class.phpのextendsしているクラスをBaseFormPropelからBaseFormPropel2に変更。/lib/form/BaseFormPropel.class.phpをBaseFormPropel2.class.phpに変更。そのファイルの中身をBaseFormPropelからBaseFormPropel2に変更。どうやらこれでもうまくいきました。なんていうか。。。微妙な解決策w

ネットで探したら、同じエラーの人がいた。symfony framework forum: Installation and setup => "Fatal error: Class 'BaseFormPropel' not found"でも、起きている状況が違うような気もするな。あと、英語よくわからない。

根本的な原因がわからないのが、ちょっと後味悪いかな。

続き:[symfony]Class ‘BaseFormPropel’ not foundエラー解決