エントリー

タグ「PHP」の検索結果は以下のとおりです。

Silexでセッションとデータベースとテンプレートを使うメモ

Silexの機能をいくつか使ってみたのでメモ。

主にSilexユーザーガイドを参考にしていますが、自分のやりやすいように解説と違っている箇所があります。Silex自体の導入はSilex導入メモに記載しています。

Silexでセッションを使う

セッションを使う仕組みは、標準で用意されている。

$app->register(new Silex\Provider\SessionServiceProvider(), array(
));

でセッションプロバイダーを使うことを宣言。あとは $app['session'] にアクセスすれば、セッションを扱うための命令を呼び出せる。

以下は参考コード。

<?php

require_once __DIR__ . '/silex/vendor/autoload.php';

$app = new Silex\Application();
$app['debug'] = true;

$app->register(new Silex\Provider\SessionServiceProvider(), array(
));

$app->get('/', function() use($app) {
  $app['session']->start();

  if ($app['session']->has('count')) {
    $count = $app['session']->get('count');
  } else {
    $count = 0;
  }

  $app['session']->set('count', ++$count);

  return 'count=' . $app['session']->get('count');
});

$app->run();

exit;

?>

Silexでデータベースを使う

Doctrine経由でデータベースに接続する仕組みが、標準で用意されている。ただしDoctrineそのものは同梱されていないので、自分で導入する必要がある。

まずはDoctrineからファイルをダウンロードする。解凍して作成されたファイルを silex/vendor/doctrine/ 内に配置する。

test / index.php
  |
  +-- silex / LICENSE
        |
        +-- src / ~略~
        |
        +-- vendor / autoload.php
              |
              +-- composer / ~略~
              |
              +-- doctrine / doctrine-mapping.xsd
              |       |      LICENSE
              |       |      package.xml
              |       |      UPGRADE_TO_2_0
              |       |      UPGRADE_TO_2_1
              |       |      UPGRADE_TO_2_2
              |       |      UPGRADE_TO_ALPHA3
              |       |      UPGRADE_TO_ALPHA4
              |       |
              |       +-- bin / ~略~
              |       |
              |       +-- Doctrine / ~略~
              |
              +-- pimple / ~略~
              |
              +-- symfony / ~略~

次に

$app->register(new Silex\Provider\DoctrineServiceProvider(), array(
  'db.options' => array(
    'dbname'   => 'データベース名',
    'user'     => 'データベース接続ユーザー名',
    'password' => 'データベース接続パスワード',
    'host'     => '接続先',
    'driver'   => 'ドライバ',
  ),
  'db.dbal.class_path'   => __DIR__ . '/silex/vendor/doctrine',
  'db.common.class_path' => __DIR__ . '/silex/vendor/doctrine'
));

でDoctrineプロバイダーを使うことを宣言。あとは $app['db'] にアクセスすれば、データベースを扱うための命令を呼び出せる。

以下は参考コード。

<?php

require_once __DIR__ . '/silex/vendor/autoload.php';

$app = new Silex\Application();
$app['debug'] = true;

$app->register(new Silex\Provider\DoctrineServiceProvider(), array(
  'db.options' => array(
    'dbname'   => 'test',
    'user'     => 'xxxx',
    'password' => 'yyyy',
    'host'     => 'localhost',
    'driver'   => 'pdo_mysql',
  ),
  'db.dbal.class_path'   => __DIR__ . '/silex/vendor/doctrine',
  'db.common.class_path' => __DIR__ . '/silex/vendor/doctrine'
));

$app->get('/', function() use($app) {
  $stmt = $app['db']->query('SELECT * FROM address');

  $result = '';
  while ($row = $stmt->fetch()) {
      $result .= $row['no'] . ' / ' . $row['name'] . ' / ' . $row['tel'] . '<br />';
  }

  return $result;
});

$app->run();

exit;

?>

Silexでテンプレートを使う

Twig経由でテンプレートを使用する仕組みが、標準で用意されている。ただしTwigそのものは同梱されていないので、自分で導入する必要がある。

まずはTwigからファイルをダウンロードする。解凍して作成されたファイルを silex/vendor/twig/ 内に配置する。

test / index.php
  |
  +-- silex / LICENSE
        |
        +-- src / ~略~
        |
        +-- vendor / autoload.php
              |
              +-- composer / ~略~
              |
              +-- pimple / ~略~
              |
              +-- symfony / ~略~
              |
              +-- twig / .travis.yml
                    |    AUTHORS
                    |    CHANGELOG
                    |    composer.json
                    |    LICENSE
                    |    package.xml.tpl
                    |    phpunit.xml.dist
                    |    README.markdown
                    |
                    +-- bin / ~略~
                    |
                    +-- doc / ~略~
                    |
                    +-- ext / ~略~
                    |
                    +-- lib / ~略~
                    |
                    +-- test / ~略~

次に

$app->register(new Silex\Provider\TwigServiceProvider(), array(
  'twig.path'       => __DIR__ . '/views',
  'twig.class_path' => __DIR__ . '/silex/vendor/twig/lib',
));

でTwigプロバイダーを使うことを宣言。(twig.path は、テンプレートを配置するためのディレクトリ)あとは $app['twig'] にアクセスすれば、Twigを扱うための命令を呼び出せる。

以下は参考コード。

<?php

require_once __DIR__ . '/silex/vendor/autoload.php';

$app = new Silex\Application();
$app['debug'] = true;

$app->register(new Silex\Provider\TwigServiceProvider(), array(
  'twig.path'       => __DIR__ . '/views',
  'twig.class_path' => __DIR__ . '/silex/vendor/twig/lib',
));

$app->get('/', function() use($app) {
  $variables['test1'] = 'これはテストです。';
  $variables['test2'] = array('テスト1', 'テスト2', 'テスト3');

  return $app['twig']->render('test.html', $variables);
});

$app->run();

exit;

?>

テンプレートは views ディレクトリ内に test.html を作成し、以下の内容を記述する。

<html>
<head>
<meta charset="utf-8" />
<title>title</title>
</head>
<body>
<h1>テスト</h1>
<p>{{ test1 }}</p>
<ul>
  <!--{% for test in test2 %}-->
  <li>{{ test }}</li>
  <!--{% endfor %}-->
</ul>
</body>
</html>

Silex導入メモ

Silexを試してみたので導入メモ。

Silexとは

PHP5.3以降で利用できる、ライトウェイトなフレームワーク。Symfony2のクラスを利用しているらしい。Symfony2では大げさすぎる場合に使えるみたい。

利用方法

公式サイトから silex.phar をダウンロードしてrequireするだけで使える。現在はphar形式にはなっていない。

pharとは

「PHp ARchive」の略で、複数のファイルをまとめたもの。

動かない

ロリポップサーバーで Class 'Silex\Application' not found とか表示された。どうやら、環境によってはpharファイルの利用は問題があるらしい。pharをバラせば普通のPHPファイルになるので、それを使えばいい。

pharコマンドを使える環境でroot権限で、silex.phar に対して以下を実行。(rootでないと「ライセンスエラー」とか表示された。)

$ phar extract -f silex.phar

作成されたファイルを、まるごと silex フォルダに突っ込む。そして silex.phar の読み込み処理を

//require_once __DIR__ . '/silex.phar';
require_once __DIR__ . '/silex/vendor/autoload.php';

のようにするとSilexを使える。

ディレクトリ構成

参考に、ディレクトリ構成とプログラムの内容全文。

  • test ディレクトリ内で動作させるとする
  • Silexは test/silex/ に配置するとする
  • 本番環境では test/silex/ にアクセス制限をかけたり、公開ディレクトリ外に設置するとよさそう
  • LICENSEファイルや説明書ファイルなどは、動作には不要(自分でどのファイルか判りやすいように書いているだけ)
test / index.php
  |
  +-- silex / LICENSE
        |
        +-- src / ~略~
        |
        +-- vendor / ~略~

test/index.php の内容は以下のとおり。

<?php

require_once __DIR__ . '/silex/vendor/autoload.php';

$app = new Silex\Application();
$app['debug'] = true;

$app->get('/', function() use($app) {
  return 'index';
});

$app->run();

exit;

?>

ブラウザソフトから index.php にアクセスして、index と表示されれば成功。

各機能の使用方法はSilexでセッションとデータベースとテンプレートを使うメモに記載。

確率を指定したランダム

単純なランダム表示は簡単だけど、「特定のメッセージが表示されやすいランダム」のような「確率を指定したランダム」が必要になったのでメモ。

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>rand</title>
</head>
<body>
<?php

$configs = array(
  array(
    'probability' => 60,
    'message'     => '60%の確率で表示されます。'
  ),
  array(
    'probability' => 30,
    'message'     => '30%の確率で表示されます。'
  ),
  array(
    'probability' => 10,
    'message'     => '10%の確率で表示されます。'
  )
);

$count = count($configs);
$max   = 0;

for ($i = 0; $i < $count; $i++) {
  $max += $configs[$i]['probability'];
}

$rand   = rand(1, $max);
$from   = 0;
$to     = 0;
$result = '';

for ($i = 0; $i < $count; $i++) {
  $from = $to;
  $to  += $configs[$i]['probability'];

  if ($from < $rand and $rand <= $to) {
    $result = $configs[$i]['message'];
  }
}

echo '<p>' . $result . '</p>';

?>
</body>
</html>

probability の値は、合計100にならなくても動作に問題はありません。あくまでも「値の大きいものが表示されやすい」というだけ。

なお、基本的な考え方は確率変更可能ランダムテキストを参考にしています。(自分が理解しやすいようにコードを書き換えましたが。)こういうのが思いつく人は凄いなぁ…。

PHPで圧縮ファイル作成(zip)

phpMyAdminの libraries/zip.lib.php を使えば、PHPのみでファイルの圧縮ができたのでメモ。

<?php

require_once 'zip.lib.php';

$zipfile = new zipfile();

//圧縮するファイルのパス
$file1 = 'test.txt';
$file2 = 'test/test.jpg';

//ファイルを追加
$zipfile->addFile(file_get_contents($file1), $file1);

//ファイルを追加
$zipfile->addFile(file_get_contents($file2), $file2);

/*
//ZIPファイルを作成する場合
if (file_put_contents('test.zip', $zipfile->file()) === false) {
  exit('error');
}
*/

//ZIPファイルをダウンロードする場合
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="test.zip"');
header('Content-Length: ' . strlen($zipfile->file()));
echo $zipfile->file();

exit;

?>

HTTP_OAuth_Consumerでの認証エラー対策

TwitterでOAuthを行うPHPプログラムを書く場合、HTTP_OAuth_Consumerクラスを使って

$consumer = new HTTP_OAuth_Consumer('CONSUMER_KEY', 'CONSUMER_SECRET');
$consumer->setToken('TOKEN');
$consumer->setTokenSecret('TOKEN_SECRET');

$response = $consumer->sendRequest('http://api.twitter.com/1/statuses/user_timeline.xml?include_rts=true&page=1', array(), 'GET');

$xml = simplexml_load_string($response->getBody());

print_r($xml);

のように処理していたのですが、6月7日から急に「This method requires authentication.」というエラーが返ってくるようになりました。

なかなか原因が解らなかったのですが、sendRequestでデータを送受信する際に

$response = $consumer->sendRequest('http://api.twitter.com/1/statuses/user_timeline.xml', array('include_rts' => true, 'page' => 1), 'GET');

とするとエラーにならなくなりました。引数を ? に続けて渡さずに、別途 array() で渡すように変更しています。

? に続けて引数を渡すのは非推奨な方法で、6月7日に非推奨な方法を廃止したのかなぁ…と思いますが、原因は不明です。「ページ送り機能が削除されて、APIが使い物にならなくなった。」とか思っていたのですが、そうではなくて良かった。ヽ(;▽;)ノ

はじめてのPHP

唐突ですが本を書きました!

はじめてのPHP

本の内容は、基本的にはPHP入門と同じ。というか、本を書くために加筆修正して、最終的には元々の内容と比べて倍くらいになりました。(^^;

最初にPHPの入門書を書く話をもらったとき、「PHP入門の内容をベースに書く」「サイトの解説は公開終了にしない」「もちろんサイトの解説の権利を譲渡したりもしない」なら書きます!で請けてみた。 ベースができているとは言え、加筆修正してから書籍用に文章を調整して…とかやっていたら、結局4ヶ月くらい書いてた。ちなみに書き始めたのは今年のはじめ。
本当はもう少し早く出版されるはずだったらしいけど、震災の影響で色々混乱していて遅れたらしい。

正直「今新たにPHPの入門書を出版しても、そんなに需要はあるかなぁ…」と思ったりはする。でもやっぱり、一度は本を書いてみたいとは思うわけで。

ちなみに今まで本について一切触れなかったのは、「何かあって出版が流れたら、カッコ悪い事この上ないな…」とか思っていたから。((((;゜Д゜)))

そんな訳ですが、よければどうぞ。(。╹ω╹。)

Twitterでの一部の発言をサイドバーに表示

少し前からTwitterには鍵をかけていますが、freoに関するツイートのみブログのサイドバーに表示するようにしてみた。更新情報とか簡単な返信とかは、ここに書いていこうと思います。

ちなみに仕組みは、

  • Twitter API で発言を取得してデータベースに保存
  • データベースから特定のキーワードを含む発言を表示

となっています。鍵を書けたアカウントでも一部の発言のみを公開できるので、それなりに需要のある仕組みかも。

設置が少しややこしいのが難点だけど。(´・ω・`)

Twitterでフォローされている人を一覧表示

Twitter API 仕様書
http://watcher.moe-nifty.com/memo/docs/twitterAPI.txt

statuses/followers の項目にフォロワーを取得する方法は書かれていますが、APIの仕様上100件までしか取得できません。ですがAPIから送られてくる next_cursor の値を使えば、続きを取得することができます。

そんな訳で書いてみたのが以下のプログラム。フォロワーをすべて取得しますが、APIを何度も呼び出すのでフォロワーが多いと重くなります。

<?php

function get_followers($screen_name)
{
  $results = array();
  $cursor  = -1;

  while (1) {
    $xml = simplexml_load_string(file_get_contents('http://api.twitter.com/1/statuses/followers/' . $screen_name . '.xml?cursor=' . $cursor));

    foreach ($xml->users->user as $user) {
      $results[] = (string)$user->screen_name;
    }

    $cursor = $xml->next_cursor;

    if ($cursor == 0) {
      break;
    }
  }

  return $results;
}

?>

以下のようにID(正確にはスクリーンネーム)を指定すると、フォロワー一覧を返してくれます。なお、鍵をかけているユーザーの情報は取得できません。

<?php

$followers = get_followers('favoritelabo');

print_r($followers);
exit;

?>

CakePHPのAuthコンポーネント利用時、暗号化を独自に行う方法

自分用にメモ。

Authコンポーネントを利用していれば、ユーザー情報登録時にパスワードを自動的に暗号化してくれます。ですがその影響で、パスワードの英数字チェックや長さチェックができません。(validate実行時は暗号化済みのため。)

回避方法は色々あるようですが、

  • Authコンポーネントによる暗号化をOFFにする
  • データベースへ格納する直前に自分で暗号化する

で対処する方法をメモ。

暗号化を回避する方法自体は、以下で紹介されています。

AuthComponentのパスワード暗号化を無効にする方法

このままだと暗号化せずにデータベースへ格納されるので、UserモデルのbeforeSaveメソッド内でAuthコンポーネントを使って暗号化を行います。具体的には以下のようなコードで暗号化できます。

function beforeSave()
{
  $this->data['User']['password'] = AuthComponent::password($this->data['User']['password']);

  return true;
}

モデル内でAuthコンポーネントを使うので、あらかじめ以下のコードでコンポーネントを読み込んでおく必要があります。

App::import('Component', 'Auth');

ひとまずこの方法で進めてみるとします。

CakePHPメモ

CakePHP1.3で躓いたところを、後々忘れないようにまとめたておいた。

最初に公式のブログチュートリアルと同じようなものを作った後、

  • 改ページの導入
  • ログイン機能の導入
  • ログイン状態保持機能の導入
  • ワンタイムトークン(CSRF対策)の導入

を簡単に解説しています。自分で色々調べつつ書いているメモなので、ツッコミ歓迎。

ページ移動

ユーティリティ

カテゴリー

検索

エントリー検索フォーム
キーワード

過去ログ

過去ログ表示フォーム
キーワード

Feed