Posts tagged PHP

WordPress の Simple Tagging プラグインで表示する関連エントリのはてブ数を表示する方法

1

このブログは Simple Tagging というプラグインを使用して各エントリにタグをつけています。このプラグインを使用するとタグから各エントリの関連エントリを自動的に表示することができます。詳しくは下記エントリをご覧ください。
WordPress でタグを使えるようにしてみた

今回はこの関連エントリのはてなブックマーク数を表示するようにする方法です。
こんなイメージです。
関連エントリにはてブ数を表示

関連エントリを表示するタグ

<?php STP_RelatedPosts(); ?>
この STP_RelatedPosts 関数の第1引数は表示フォーマットを指定するので、そこにはてブ数を表示するようなフォーマットを指定します。
<?php STP_RelatedPosts('<li><a href="%permalink%" title="%title% (%date%)">%title%</a> <a href="http://b.hatena.ne.jp/entry/%permalink%"><img src="http://b.hatena.ne.jp/entry/image/%permalink%" alt="" /></a>'); ?>

これで関連エントリにはてブ数が表示されるようになりました。

WordPress ではてなブックマーク数を表示

2

少しづつはてブされるようになってきたので、各エントリーのタイトルの横にはてなブックマーク数とはてブを表示するようにしてみました。

はてブボタンを表示

http://d.hatena.ne.jp/images/b_entry.gif からはてブアイコンをダウンロードして自分のサーバにアップロードします。

表示したい場所に下記タグを追加します。

<a href='http://b.hatena.ne.jp/entry/<?php the_permalink(); ?>'><img src='/images/b_entry.gif' width='16' height='12' style='border: none;' alt='このエントリーを含むはてなブックマーク' title='このエントリーを含むはてなブックマーク' /></a>

参考:はてなブックマーク – ヘルプ – 自分のブログに「このエントリーを含むはてなブックマーク」ボタン

はてなブックマーク数を表示

表示したい場所に下記タグを追加します。

<a href='http://b.hatena.ne.jp/entry/<?php the_permalink(); ?>'><img src='http://b.hatena.ne.jp/entry/image/<?php the_permalink(); ?>' alt='' /></a>

参考:はてなブックマーク – ヘルプ – 自分のブログに「○○users」を表示

HTTP_Request を使用してファイルをアップロードする方法

1

PEAR の HTTP_Request を使用してファイルをアップロードする方法です。

<form action='POST_URL' method='post' enctype='multipart/form-data'>
<input type='text' name='title'>
<textarea name='body'></textarea>
<input type='file' name='upload_file'>
<input type='submit'>
</form>

上記のような HTML でファイルをアップロードする場合と同じような処理をするには、下記のように HTTP_Request を使用します。

// POST パラメータ
$post_data = array(
    'title' => $title,
    'body'  => $body,
);
// アップロードパラメータ
$upload_file = array(
    'name' => 'file',
    'path' => '/path/to/file',
);
// アップロード
$rs = http_send(POST_URL, $post_data, $upload_file);

function http_send($url, $params, $upload_file=null) {
    $req = new HTTP_Request();
    $req->setMethod(HTTP_REQUEST_METHOD_POST);

    foreach ($params as $key => $val) {
        $req->addPostData($key, $val);
    }

    $req->setURL($url);
    if ($upload_file) {
        $res = $req->addFile($upload_file["name"], $upload_file["path"]);
        if (PEAR::isError($res)) {
            echo $res->getMessage();
            exit;
        }
    }

    if (!PEAR::isError($req->sendRequest())) {
        return $req->getResponseBody();
    } else {
    	return false;
    }
}

参考:PEAR :: Manual :: ファイルアップロード

phpPgAdmin でログインできない

0

普段は MySQL ばかり使用しているのですが、PostgreSQL を使用する必要があり、phpPgAdmin を使うことにした。
開発用のサーバには phpPgAdmin がインストールされているが、ブラウザで閲覧できるようにはまだしていなかった。

Open Tech Press | phpPgAdmin:Web開発者向けのPostgresクライアントツール を参考に /usr/share/phpPgAdmin にインストールされている phpPgAdmin をブラウザでアクセス可能にした。

/etc/http/conf/httpd.conf に下記を追加

Alias /phppgadmin /usr/share/phppgadmin/
<DirectoryMatch /usr/share/phppgadmin/>
  Options +FollowSymLinks
  AllowOverride None
  order deny,allow
  deny from all
  allow from localhost
</DirectoryMatch>

これでブラウザから http://example.com/phpPgAdmin/ でアクセスできるようになった。
しかし、PostgreSQL のユーザでログインしようとするとエラーになる。

これは シン石丸の電脳芸事ニッキ: debian 3.1へのphppgadminのインストール後の設定 を参考にして解決。

/etc/postgresql/pg_hba.conf に下記を追加
host all all 127.0.0.1 255.255.255.255 trust

これで無事 phpPgAdmin にログインできました。

CakePHP Security コンポーネントのまとめ

1

CakePHP の Security コンポーネント の動作を調べたのでまとめておきます。
この Security コンポーネントをうまく使用すればクロスサイトリクエストフォージェリ(CSRF) を防ぐことができるでしょう。

トークンの使用

フォームにワンタイムトークンを実装する方法です。

コントローラの beforeFilter メソッドでトークンをチェックするアクションを指定
function beforeFilter() {
    $this->Security->requireAuth('login');
}
ビューのフォーム内にトークンを設定

<?php echo $html->formTag(); ?>
トークンが hidden 属性で生成される

トークンが一致しない場合

requireAuth で指定したアクションに POST でアクセスがあるとセションに保存したトークンとフォームから送られてきたトークンが一致するかチェックします。またそのほかにトークンの有効期間もチェックします。有効期間は CAKE_SECURITY の設定により違います。

CAKE_SECURITY 有効期間
high 10分
medium 100分
low 300分

トークンが一致しないと SecurityComponent の blackHole メソッドが実行されます。このメソッドでは
header('HTTP/1.0 404 Not Found');
を出力して exit します。(画面は空白)

任意の処理を実行したい場合は blackHoleCallback でコールバック関数を指定します。
設定できるのは同じコントローラ内のアクションのみになります。

function beforeFilter() {
    $this->Security->blackHoleCallback = "securityError";
    $this->Security->requireAuth('login');
}

function securityError() {
	die("security error!");
}
トークンチェックをするアクションを複数指定するときはカンマでつなげる

$this->requireAuth('login', 'delete');

特定のコントローラからのポストのみ許可する

$this->Security->allowedControllers = array("users");
これを指定するとたとえトークンが一致しても許可のないコントローラからのポストの場合は blackHole メソッドを実行します。

特定のアクションからのポストのみ許可する

$this->Security->allowedActions = array("action");
これを指定するとトークンが一致しても許可のないアクションからのポストの場合は blackHole メソッドを実行します。

ポストのみ受け付けるようにする

$this->requirePost('login');
これはトークンとは違い、POST のみ許可して GET でのアクセスを不可にします。
/users/login/ のような URL でのアクセスも GET なので不可になります。
POST の処理だけを実行したいようなアクションに使用します。

CakePHP Textヘルパーの truncate を全角文字に対応させてみた

5

CakePHP の Text ヘルパーに truncate という指定された文字列を任意の長さに省略するメソッドがあります。
しかし、このメソッドは全角文字を考慮していないため全角文字に用いると文字化けすることがあります。
そこでこのメソッドを全角文字に対応させてみました。

function truncate($text, $length, $ending = '…', $exact = true) {
    if (strlen($text) < = $length) {
        return $text;
    } else {
        mb_internal_encoding("UTF-8");
        if (mb_strlen($text) > $length) {
            $length -= mb_strlen($ending);
            if (!$exact) {
            $text = preg_replace('/\s+?(\S+)?$/', '', mb_substr($text, 0, $length+1));
            }
            return mb_substr($text, 0, $length).$ending;
        } else {
            return $text;
        }
    }
}

直接 Text ヘルパーを修正するとバージョンアップなどのときに困るので、
cake/libs/view/helpers/text.php を app/views/helpers/mb_text.php にコピーしクラス名を
class MbTextHelper extends Helper{
として、truncate メソッドを上記のように修正しました。

使用するときはコントローラ内で、
var $helpers = array("MbText");
view で
echo $mbText->truncate("あいうえおかきくけこ", 5, "…", true);
とすると
あいうえ…
と表示されます。

CakePHP find や findAll の条件指定にちょっとだけ便利な postConditions

1

CakePHP の コントローラに postConditions というちょっとだけ便利なメソッドがありました。

cake/libs/controllers.php

function postConditions($data) {
    if (!is_array($data) || empty($data)) {
        return null;
    }
    $conditions = array();

    foreach($data as $model => $fields) {
        foreach($fields as $field => $value) {
            $conditions[$model . '.' . $field] = $value;
        }
    }
    return $conditions;
}

例えば検索をするフォームなどで User.name で検索するような場合

view で
input('User/name');
と指定すると$this->data は

Array
(
    [User] => Array
        (
            [name] => 山田
        )
)

この $this->data を postConditions に渡すと
$data = $this->postConditions($this->data);
$data は

Array
(
    [User.name] => 山田
)

となり、このまま find や findAll に渡すことができます。
$this->User->find($data);

参考:CakePHP マニュアル
7.2. コントローラの関数

11月に読んだ本

2

最近は仕事関係の本や自己啓発関係の本が多い。特に今年は小説を読んでないので、今月は少し小説を読もうと思っています。

決算書がスラスラわかる 財務3表一体理解法 (朝日新書 44) (朝日新書 44)

決算書がスラスラわかる 財務3表一体理解法 (朝日新書 44) (朝日新書 44)

あたりまえだけどなかなかできない仕事のルール (アスカビジネス)

あたりまえだけどなかなかできない仕事のルール (アスカビジネス)

ウェブ時代をゆく ─いかに働き、いかに学ぶか (ちくま新書 687)

ウェブ時代をゆく ─いかに働き、いかに学ぶか (ちくま新書 687)

なぜ、エグゼクティブはゴルフをするのか?

なぜ、エグゼクティブはゴルフをするのか?

ちょいデキ! (文春新書 591)

ちょいデキ! (文春新書 591)

すごい「実行力」

すごい「実行力」

なぜ、エグゼクティブはゴルフをするのか?

なぜ、エグゼクティブはゴルフをするのか?

仕事に活かす!本200%活用ブック

仕事に活かす!本200%活用ブック

WEB+DB PRESS Vol.41

WEB+DB PRESS Vol.41

お金は銀行に預けるな 金融リテラシーの基本と実践 (光文社新書)

お金は銀行に預けるな   金融リテラシーの基本と実践 (光文社新書)

プログラミングPHP 第2版

プログラミングPHP 第2版

CakePHPガイドブック

CakePHPガイドブック

忙しいパパのための子育てハッピーアドバイス

忙しいパパのための子育てハッピーアドバイス

ケータイ業界52人が語る「戦略」の裏側

ケータイ業界52人が語る「戦略」の裏側

カリスマ・コンサルタントの稼ぐ超思考法 ~仕事と人生に効く「問題解決力」が身につく20の方法~

カリスマ・コンサルタントの稼ぐ超思考法 ~仕事と人生に効く「問題解決力」が身につく20の方法~

自転車生活の愉しみ

自転車生活の愉しみ

CakePHP 環境によってデータベースを切り替える

2

テストデータを入れるなどテストと環境でデータベースを切り替えたいときがあります。
CakePHP でそれをやる方法です。

モデルの $useDbConfig に app/config/database.php で定義されている $default がデフォルトで使用されます。
database.php に $test など使用したいデータベースの分だけ定義を増やし、
それをモデルで
$this->useDbConfig = 'test';
のように指定すればいいだけです。

app/app_model.php のコンストラクタで設定するのが一番簡単かもしれません。

CakePHP 環境に応じてDBの設定を変える | Shin x blog
で色々な方法が紹介されています。

“CakePHPで超簡単スケーラビリティ” フォーラム – CakePHP Users in Japan
また、この $useDbConfig を使用して

「マスターとスレーブのMYSQLサーバがあります。レプリケーション機能で、マスターからスレーブにデータが常にコピーされています。データの更新・追加はマスターに対して行い、データの検索はスレーブで、という場合にはどうすればよいでしょうか?」

というような場合のすごく簡単な方法が紹介されています。
モデルの beforeSave,afterSave,beforeDelete,afterDelete を使用してマスターとスレーブを切り替えています。

CakePHP MySQL で文字化けを防ぐ設定

4

MySQL で文字化けを防ぐためには
SET NAMES utf8
のように SET NAMES を実行するのが有効なのですが、これを app/config/database.php で設定する方法です。

'encoding'=>'文字コード'
をデータベースの設定項目に追加してやるだけです。

具体的には app/config/database.php が下記のようになります。

var $default = array(
    'driver' => 'mysql',
    'connect' => 'mysql_connect',
    'host' => 'localhost',
    'login' => 'user',
    'password' => 'password',
    'database' => 'dbname',
    'prefix' => '',
    'encoding' => 'utf8'
);


cake/libs/model/dbo/dbo_mysql.php
で下記のように実行されています。

function connect() {
    (略)
    if (isset($config['encoding']) && !empty($config['encoding'])) {
        $this->setEncoding($config['encoding']);
    }

    return $this->connected;
}
function setEncoding($enc) {
    return $this->_execute('SET NAMES ' . $enc) != false;
}
Go to Top