CakePHPのコアライブラリの使い方の勉強として、ファイルをダウンロード(ストリームでファイルを保存)するアプリケーションを作ってみたときのメモです。今回使ったコアライブラリは、HttpSocket, Folder, Fileの3つです。
 今回の記事は、CakePHPで作ったアプリケーションで何かしらのファイルをダウンロードさせるのではなく、どこかしらから取ってくる話です。ご注意ください。
Cookbook 2.x
開発環境
開発環境は以下の通りです。MAMP 2.0.5を使って開発を行いました。また、XAMPP 1.8.1でも動作確認を行いました。
Mac 開発環境| ソフトウェア | バージョン | 
|---|
| MAMP | 2.0.5 | 
| PHP | 5.3.6 | 
| CakePHP | 2.2.5 | 
Windows 動作確認環境| ソフトウェア | バージョン | 
|---|
| XAMPP | 1.8.1 | 
| PHP | 5.4.7 | 
| CakePHP | 2.2.5 | 
GitHubからCakePHPのZipballをダウンロードしてみる
CakePHPでファイルをダウンロードするアプリケーションの例として、GitHubからCakePHPのZipballをダウンロードしてみたいと思います。
 基本的には、CookbookのDownloading the resultsにあるサンプル通りで良いのですが、せっかくなので、FolderクラスとFileクラスも使ってみたいと思います。(サンプルはfopen, fcloseを利用している)
 ソースコードは以下の通りです。パスの指定や、例外処理等は省略しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17  | <?php App::uses('AppModel', 'Model'); App::uses('HttpSocket', 'Network/Http'); App::uses('Folder', 'Utility'); App::uses('File', 'Utility');   class Github extends AppModel {  public function download() {  $http = new HttpSocket();  $dir  = new Folder(WWW_ROOT . 'files' . DS . 'cakephp', true, 0755);  $file = new File($dir->path . DS . 'cakephp.zip', true, 0644);  $file->open('wb');  $http->setContentResource($file->handle);  $http->get('https://github.com/cakephp/cakephp/archive/master.zip', null, array('redirect' => true));  $file->close();  } }  | 
10行目で、Folderクラスのインスタンスの生成と同時に、フォルダの作成を行っています。素のPHPで同様の処理を行う場合は、以下のように書くと思いますが、Folderクラスを使えば、もろもろの処理を任せることができるので、記述量も減って、お手軽ですね。
 | if (!file_exists(WWW_ROOT . 'files' . DS . 'cakephp')) mkdir(WWW_ROOT . 'files' . DS . 'cakephp', 0755);  | 
13行目、 HttpSocket::setContentResource()メソッドで、ストリームを使って結果を取得するようにし、14行目の HttpSocket::get()メソッドで、取得したいファイルに対してGETリクエストしています。GitHubでは、サイト上に提示されているURLから転送がかかってファイルがダウンロードされるようになっていますので、HttpSocket::get()メソッドの第3引数で、リダイレクトを許可しています。以下のように、転送先のURLを指定してもよいです。
 | $http->get('https://nodeload.github.com/cakephp/cakephp/zip/master');  | 
以上です。
今回のサンプルのファイルパスは固定でしたが、実際には、スクレイピングをして得たバイナリデータを保存するツールを作ってみました。それについては、またどこかの機会で。