Home > PHP Archive

PHP Archive

第五回CakePHP勉強会に行ってきた

  • 2010-05-30 (日)
  • PHP

第五回CakePHP勉強会に行ってきました。
以下、覚書の印象に残った事柄を抜粋して書きます。

内容

// {{{ 特報目玉イベント2010 安藤さん

海外からスカイプを通してのプレゼンです。
今年のCakeMatsuriの紹介をしてくれました。
発表のスライドショーです。http://www.slideshare.net/yandod/20100529-phpday

オールナイト!!!!!!!
朝9時から翌日5時まで
講演スペースと開発スペースが用意される?各自開発するスペース
未発表作成・機能のコンテストを開催
開発タイム終了後いデモを実施
作業スペースは終夜可
レクレーションやイベントを開催予定
Litiumの思想をセッション
ワークショップ
入門者向け、中級者向け、Litium入門者
プラグインライブラリ賞
wordpressやsymfonyでも
ハッカソン賞
イベント開始後にテーマに沿って開発
ドキュメント賞
ベンチマークなどなど
協賛して頂ける企業を募集
コンテスト各賞のスポンサー
ディナー協賛などなど
運営スタッフ募集

かなりおもしろそーー!!!!!
twitterの方で情報が流れます。@phpmatsuri
// }}}

// {{{ CakePHP 1.3 Stable cakephperさん
発表資料です。http://www.slideshare.net/ichikaway/cakephp-tokyo5

1.3の新機能

Routes
Prefix Routing
Adminルーディングと同じ扱いに
RouteClass
ルーティング処理マッチング時に自作クラス呼び出し
DBの値を見てマッチング処理を行う
→例1:該当のslugがDBにあればroutingする
→例1:urlの一部変更でリダイレクト

config/routes.php

App::import( 'Lib', 'routes/SlugRoute' );
Router::connect(
    '/:slug',
    array( 'controller' => 'posts', 'action' => 'view' ),
    array( 'routeClass' => 'SlugRoute' )
);

app/libs/routes/slug_route.php

class Slug extends CakeRoute {

    function parse( $url ) {

        $params = parent::parse( $url );

        App::import( 'Model', 'Post' );

        $Post = new Post();

        $count = $Post->find( 'count', array( 'conditions' =>
            array( 'Post.slug LIKE ?' => $params['slug'] . '%' ) ) );

        if( $count ) {
            return $params;
        }
        return false;
    }
}

Virtual Fields
DBカラムを仮想定義して、Fieldとして扱える
詳細:http://book.cakephp.org/ja/view/1608/Virtual-fields
  ;http://d.hatena.ne.jp/hiromi2424/20100204/1265274976

Validation
マルチバイト対応
maxLength()などはmb_strlen()を使用
mb_strlen()が定義されていなければマルチバイトクラスのMultibyte::strlen()を利用
国別のルールを適用
Phone, postcode, SSN
例;日本のpostcodeなら222-3333というルール
→例あるからスライド参照しろ

// }}}

// {{{ Ktai Library on CakePHP1.3 MASA-Pさん

ライブラリクラスの分割
絵文字や機種情報なとをすべて読み込むとメモリを消費するので
→サブクラス化して必要なものだけ読み込むようにした

絵文字コンバートルーチンの改良
絵文字総当たりで置換していたためとても重かったためアルゴリズムを改良
異なるエンコーディングへの変換の場合に
絵文字のキャッシュ機能を付加

IPアドレスによるキャリア判定を搭載!!!!!!!!!!!
ユーザーエージェント偽装によるアクセスを対応

// }}}

// {{{ コアライブラリのエレガントなハック hiromi2424さん
http://github.com/hiromi2424/hack_plugin

どうしてハックするの

アプリケーションポリシーの埋め込み
sessionハイジャック対策でlogを吐きたいときなどなど

どうやってハックするの
エイリアスみたいにマップされたオブジェクトを置換する

マップングされたオブジェクトの置換
Component::_loaded[ $key ] // $keyにくるのはコンポーネントの名前
オブジェクトへのリファレンス
フックするタイミング
initialize()

init() ←オブジェクトのマッピング
initialize()←プロパティなどの設定
startup()←staring process処理を開始

// }}}

// {{{ twitterとcloud serverとcakeで新規サービス 谷井さん
スライド:http://docs.google.com/present/view?id=d4b7q8p_21cq5hkjg8

twitterアプリの問題
APIの返事が遅すぎる

1時間に150回制限
oauthを使う
APIの返事が遅すぎる
twitterのデータをDBに保存してキャッシュすればいけんじゃない?

rackspaceはいい
スケールの設定
DNSの逆引きができる

負荷対策
apatchの設定
MaxClient 150 → 1000
MaxKeepAliveRequests 100 → 20000

mysqlの設定
my.cnfをいじる
[mysqld-5.0]
max_connections=450
thread_cache=450
key_buffer_size=10M
// }}}

以下LTです
「WordPressの中でCakePHPを使って連携する」
スライド:http://www.slideshare.net/karadweb/cakephp-and-wordpress
おもしろい。自分でも動かしてみようかな。

「CakePHPでjQueryを使ってみた」
http://github.com/nano-eight
スライド:http://www.slideshare.net/nanoeight/cakephpjquery-4357936
素晴らしすぐる!jQueryのプラグインをヘルパーで利用できるようにする。
使わせてもらいます!

「CakePHP tips for mys next project」
スライド:http://bit.ly/9yFAps
参考になるサイトを紹介してくれました。

「あのCMS eZ publishをCakePHPのModelにしちゃう」
スライド:http://prezi.com/ugsu8hwgypud/datasource-for-ez-publish-in-cakephp/
eZ publishとCakePHPの連携方法です

実”戦”CakePHP Plugin」
スライド:http://www.slideshare.net/k1LoW/cakephp-plugin-4364102
pluginの紹介でした。

所感

自分的にはKtai Libraryがip addressチェックを実装してくれていることがうれしいですね。
jQueryプラグインをヘルパーで吸収して利用出来るようにしたnano_eightさんのサンプルとソースはかなりそそられます。
「勉強会は懇親会が本番です。」こういうふうに言う勉強会は珍しいですよね。
運営者が勉強会を運営するにあたって大切にしていることが、勉強会で出逢う人との「つながり」だそうです。
やはり運営にそういう意識があるからなのか、アットホームな勉強会になりとても楽しいものでした。
この場でお礼申し上げます。運営者の皆様、また発表者の皆様ありがとうございました。

話は変わりますが、勉強会で全員にプレゼントされたマシュマロです。http://twitpic.com/1s1rmx
かわいいですね。

ではでは

Ktai Library勉強会に行った

  • 2010-04-25 (日)
  • PHP

第二回目が開催されたので行ってきましたー。

概要

アジェンダとしては、「PHPで作る携帯サイト-デベロッパーズガイド-」の第五章を読んでローカルで実装するのみといったかなりシンプルなものです。

ただ特典というかかなりうれしいのが本の著者であるMASA-Pさんがサポートとして出席してくれていることです。
分からないことや、質問は直接著者に問うことができます。またまた誤植の報告などもこの場ですることもw・・。

実際勉強会の雰囲気はモクモク開発を行う人、談笑しながら開発を行う人、MASA-Pさんに質問をしながら開発を行う人それぞれです。

所感

本に沿って勉強していく中で、だいたい躓くところが決まっているようでした。今回でいうと、configurationモデルの存在です。cakephpにもともとあるconfigureクラスと勘違いしてモデルの生成をしないで開発を進めていくと躓きます。あらかじめconfig/sqlにあるソースでテーブルを作成しておきましょう。また後々にシェルの説明がある箇所で躓くことが多いようです。こういう場で発見できた躓きポイントは、後から勉強する人たちのためにサポートサイトに残しておきたいですね。

あと、今後の勉強会ではKtai Libraryを使用した携帯サイト開発実体験というライトニングトークがあったらいいですよねー。公式サイトで使用しました、でもこういう苦労がありました。みたいな。。今のところないなら、自分でやりますか、携帯サイト作りますか!!そんなこんなの所感です。

開催してくれたyashioさん、会場提供してくれたE2さん、サポートで来てくれているMASA-Pさん、ありがとうございました。

フレームワークを作る ルーティング処理 調査編 その3

  • 2010-03-16 (火)
  • PHP

Url Routing with PHPを紹介してきました。このシリーズはラストみたいです。ルーティング処理だけでなく、MVCフレームワークのCを重点的にした単純なフレームワークを作成したところで完了みたいですね。元ネタはこちらです。
最後にデモとサンプルソースのダウンロードがありますが、URLからコントローラーとアクションの指定まで考慮している作りみたいです。

このシリーズを読んでき来た人たちへ。今までのコードに多少修正を加えました。多少ディレクトリ構成とAxial_URLInterpreterとAxial_Command objectを、多くはAxial_CommandDispatchクラスです。今回新たにAxial_Controllerというクラスを作成していきます。

フロントコントローラからコントローラーへアクセスするようにしましょう。方法として、名前のつけ方とディレクトリ構成のルールを決めて、各コマンド(アクション)を実行させるようにしましょう。コマンドが実行されるとき、該当のコントローラーが読み込まれ、executeメソッドが読まれるようにします。

<?php
/**
  * コントローラー実行クラス
  */
class Axial_CommandDispatcher
{
    var $Command;

    //  コンストラクタ 実行するコマンド(コントローラー)の格納
    function Axial_CommandDispatcher(&$command)
    {
        $this->Command = $command;
    }

    // 指定したコントローラーが存在するか
    function isController($controllerName)
    {
        if(file_exists('axial/controllers/'.$controllerName.'/controller.'.$controllerName.'.php'))
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    // コントローラー実行
    function Dispatch()
    {
        $controllerName = $this->Command->getControllerName();

        //  指定したコントローラーが存在していなかったらエラーコントローラークラスを指定
        if($this->isController($controllerName) == false)
        {
            $controllerName = 'error';
        }

        // 指定したコントローラーを読み込む
        include('axial/controllers/'.$controllerName.'/controller.'.$controllerName.'.php');

        // インスタンス生成・実行
        $controllerClass = $controllerName."Controller";
        $controller = new $controllerClass($this->Command);
        $controller->execute();
    }
}
?>

include(’axial/controllers/’.$controllerName.’/controller.’.$controllerName.’.php’);の箇所を見て分かるように、コントローラー名に使用するディレクトリを作成し、実行するファイル名もcontrollerコントローラー名.phpのように名前付しなければならないような作りにしています。

自分でコントローラーを追加していく中で継承しなければいけないクラスがあります。Axial_Controllerです。Axial_Controllerでは、ディスパッチコントローラーから(Axial_CommandDispatcher)execute()が必ず呼ばれ、指定したアクションを実行する処理をします。指定したアクションがなかったら_error()関数を実行し、そもそも指定アクションがnullだったら_default()関数を実行します。指定アクションの命名規則は_を頭に付けるようにしています。

<?php
class Axial_Controller
{
    var $Command;

    // コンストラクタ
    function Axial_Controller(&$command)
    {
        $this->Command = $command;
    }

    // アクションの指定がなければ、この関数が呼ばれる
    function _default()
    {
    }

    // 指定したアクションがなければ、この関数が呼ばれる
    function _error()
    {
    }

    // ディスパッチャからこの関数が呼ばれる。アクションの振り分け。
    function execute()
    {
    	// アクション取得
        $functionToCall = $this->Command->getFunction();

        // アクションがnull
        if($this->Command->getFunction() == '')
        {
            $functionToCall = 'default';
        }

        //  指定したアクションがない
        if(!is_callable(array(&$this,'_'.$functionToCall)))
        {
            $functionToCall = 'error';
        }

        // 指定したアクションを実行
        call_user_func(array(&$this,'_'.$functionToCall));
    }
}
?>

あとアクションの指定ができるようになったことで、URLのパース処理も多少修正されているはずです。ちょっと見てみましょう。

<?php
class Axial_URLInterpreter
{

    var $Command;

    function Axial_URLInterpreter()
    {
        $requestURI = explode('/', $_SERVER['REQUEST_URI']);
        $scriptName = explode('/',$_SERVER['SCRIPT_NAME']);
        $commandArray = array_diff_assoc($requestURI,$scriptName);
        $commandArray = array_values($commandArray);
        $controllerName = $commandArray[0];

        // ここが追加された箇所
        $controllerFunction = $commandArray[1];

        $parameters = array_slice($commandArray,2);

        // ルートで実行されているか
        // コントローラーの指定がなかったらrootコントローラーを指定
        // _defaultアクションが実行される
        if($controllerName == '')
        {
            $controllerName = 'root';
        }

        $this->Command = new Axial_Command($controllerName,$controllerFunction,$parameters);
    }

    function getCommand()
    {
        return $this->Command;
    }
}
?>

$controllerFunction = $commandArray[1];が追加されていますね。/でexploadされたものに0番目にコントローラー名、1番目にアクション名がくるだろうってだけですね。

他に特筆すべきことは、その2とその3のindex.phpを比べるとルーティング処理とコントローラーの呼び出し部分の処理は変わっていないのですが、HTMLの記述がなくなっています。各コントローラーのアクションで呼び出しされるようになっています。確かにMVCのCに重点的に実装したフレームワークになっているようです。

デモとサンプルコードがこちらに公開されています。

とりあえず、このチュートリアルは以上になります。

このチュートリアルを書いたDoug Hillさん。Thank you!!

ではでは。

フレームワークを作る ルーティング処理 調査編 その2

  • 2010-03-16 (火)
  • PHP

前回の続きです。

今回は第2弾です。元ネタはこちら

前回の例には2点問題があるので、解決していきましょう。
1点目に、URLをパースする方法
2点目に、コマンドの実行がswitch文での振り分け

目的は、もっとフレキシブルなURLの解釈をさせることです。そのために基本的なコマンドオブジェクトを作成していきます。

<?php
class Axial_Command
{
        var $commandName = '';
        var $parameters = array();

        // コマンド名格納、パラメータ格納
        function Axial_Command($commandName,$parameters)
        {
            $this->commandName = $commandName;
            $this->parameters = $parameters;
        }

        // コマンド名取得
        function getCommandName()
        {
            return $this->commandName;
        }

        // パラメータ格納
        function getParameters()
        {
            return $this->parameters;
        }
}
?>

次にURLをパースするクラスが必要です。前回で紹介したパース処理と上の処理を使ってコマンドオブジェクトを作成します。

<?php
class Axial_UrlInterpreter
{
	var $command;
	function Axial_UrlInterpreter()
	{
		$requestURI = explode('/', $_SERVER['REQUEST_URI']);
		$scriptName = explode('/',$_SERVER['SCRIPT_NAME']);
	for($i= 0;$i < sizeof($scriptName);$i++)
	{
		if ($requestURI[$i]	== $scriptName[$i])
		{
			unset($requestURI[$i]);
		}
	}

	$commandArray = array_values($requestURI);
	$commandName = $commandArray[0];
	$parameters = array_slice($commandArray,1);
	$this->command = new Axial_Command($commandArray[0],$parameters);

	}

	function getCommand()
	{
		return $this->command;
	}
}
?>

最後にコマンドオブジェクトを実行箇所に渡します。まだこの時点ではコードをシンプルにさせたいのでswitch文を使用しておきます。

<?php
class Axial_CommandDispatcher
{
    var $command;
    function Axial_CommandDispatcher($command)
    {
        $this->command = $command;
    }

    function Dispatch()
    {
        switch ($this->command->getCommandName())
        {
            case 'commandOne' :
                include('commandone.php');
                break;
            case 'commandTwo' :
                include('commandtwo.php');
                break;
            case '':
                include('root.php');
                break;
            default:
                include('default.php');
                break;
        }
    }
}
?>

今回の挙げたものを統合した例です。前回に作成した.htaccessが必要です。動作するデモとサンプルソースがこちらからダウンロードできます。

// 今回例に挙げたファイル読み込み
include('axial.command.php');
include('axial.urlinterpreter.php');
include('axial.commanddispatcher.php');

// URLパース処理 コマンド名取得 axial.command.phpにコマンド名とパラメータ格納
$urlInterpreter = new Axial_UrlInterpreter();

// 上のパース処理からコマンド名取得
$command = $urlInterpreter->getCommand();

// 実行処理にコマンド名格納
$commandDispatcher = new Axial_CommandDispatcher($command);

// コマンド実行
$commandDispatcher->Dispatch();

次にチュートリアルでswitch処理を直します。

以上です。

ではでは。

フレームワークを作る ルーティング処理 調査編 その1

  • 2010-03-15 (月)
  • PHP

ルーティング処理を調査します。
ルーティングの設定によってURLの構成とロジックファイルの構成が変わってくるので重要な部分です。

以下のサイトをまず見てみましょう。ルーティング処理のチュートリアルみたいですね。
Url Routing with PHP – Part One

ダメな例から挙げていってなぜダメかを説明しながらブラッシュアップするチュートリアルみたいです。

まず、.htaccessから紹介しています。

Options +FollowSymLinks #1
IndexIgnore */* #2
# Turn on the RewriteEngine
RewriteEngine On #3
# Rules
RewriteCond %{REQUEST_FILENAME} !-f #4
RewriteCond %{REQUEST_FILENAME} !-d #5
RewriteRule . index.php #6

#1 FollowSymLinksはシンボリックリンクのリンク先に辿れることを許可します
#2 「IndexIgnore命令はディレクトリをリスト表示しているときに隠すためのファイルのリストに追加します」だそうです。ワイルドカードで/を囲むって意味はすべてのファイルってことなんですかね??
#3 「mod_rewriteを使用するという宣言」だそうです。
#4 存在するファイルがなかったらtrue(下の処理にいく) / あったらfalse
#5 存在するディレクトリがなかったらtrue(下の処理にいく) / あったらfalse
#6 すべてindex.phpを実行しろ

みたいな感じだと思いまぷ(汗

エントリポイントを作成していきましょう
エントリポイントとは起点となる処理を意味します。

単純なルーティングを設定してみましょう。URLをスラッシュで区切る方法です。
例1:www.example.com/command/parameter1/parameter2/

$requestURI = explode('/', $_SERVER['REQUEST_URI']);

Array ( [0] => [1] => command [2] => parameter1 [3] => parameter2 [4] => )

しかしこの例は、commandの前にディレクトリが一つでも噛んでいると正常に動作しません。(フロントコントローラ-ここではエントリポイントのこと-がルートディレクトリでないと正常に動作しません)
例えば、次のURL:www.example.com/myapps/app1/command/parameter1/parameter2/
(commandの前にapp1が入っている。)
この場合$requestURIは次のようになります。

Array ( [0] => [1] => myapps [2] => app1 [3] => command [4] => parameter1 [5] => parameter2 [6] => )

myappsとapp1が邪魔なのでこれを除去するためには$_SERVER['SCRIPT_NAME'] の変数が必要です。

$scriptName = explode('/',$_SERVER['SCRIPT_NAME']);

中身は

Array ( [0] => [1] => myapps[2] => app1 [3] => index.php )

以下が不要なURL(パスと実行スクリプト)を消去する処理です。

$requestURI = explode('/', $_SERVER['REQUEST_URI']);
$scriptName = explode('/',$_SERVER['SCRIPT_NAME']);

for($i= 0;$i < sizeof($scriptName);$i++)
{
    if ($requestURI[$i]     == $scriptName[$i])
    {
                unset($requestURI[$i]);
    }
}
$command = array_values($requestURI);

以下が$commandの中身です。パスと実行スクリプトが失くなっています。

Array ( [0] => command [1] => parameter1 [2] => parameter2 [3] => )

実行コマンドを指定するスクリプトを書いてみましょう。

switch($command[0])
{
      case 'commandOne' :
                echo 'You entered command: '.$command[0];
                break;
      case 'commandTwo' :
                echo 'You entered command: '.$command[0];
                break;
      default:
                echo 'That command does not exist.';
                break;
}

こんなんブサイク過ぎですね。次のチュートリアルで改善されたスクリプトがあるますのでご安心を。

以下に実際に振る舞うサンプルが紹介されています。examples.phpaddiction.com/urlrouter/part_1/

次のチュートリアルはルーティング処理をクラスにまとめて、名前空間を使用することをやります。

フレームワークを作る 初級者からの脱却 調査編

  • 2010-03-04 (木)
  • PHP

フレームワークを自分で作れるようになりたい!

というか、CakePHPやら、Ethnaやら、Symfonyやら、ついでにCodeIgnighterだって、コアファイルと付属品が多すぎて実力がにぇ自分には(汗)把握できにぇ。

ということで自分で作ってみたらそれらの設計思想やらコードの理解が深まるんでないの?さらには自分のスキルも高まるんでないの?

よし!作るか、作りながらパクってもいいから、とにかく一から理解してみよう!

自分で景気付けしたわけですが、そんなこんなでこれから色々調べつつ自作フレームワーク完成を目標に挑戦してみようと思います。

まずは「PHP 自作フレームワーク」でGoogle先生に問い合わせましょう。

うん、けっこう作り方ありますね。

The symfony platform: Create your very own framework
これなんてほぼ作り方網羅してるんじゃないですかね。Symfonyを作成してる方かな。ただSymfonyのsfCoreAutoLoadを使用していて、それを前提に構築していくんですけど、結局コアな部分は大きいライブラリ。。かなり良い資料でもしかしたら解答以上のものかもしんないけど、雰囲気しか分からないです〜泣。
よく出てくる言葉「ジェネリック」。忘れてます。wikipediaだと

ジェネリック(総称あるいは汎用)プログラミング (generic programming)はデータ形式に依存しないコンピュータプログラミング方式。

これはデータ型でコードをインスタンス化するのか、あるいはデータ型をパラメータとして渡すかということに関わらず、同じソースコードを利用できるということである。

なるほど。それでこの例のものを自分の技術レベルで書ければ最高。けど、コア部分が高度。まぁ迷った時にこの設計方針と記述内容を参考にするくらいでいいかな。

 
次行ってみます。
PHPフレームワーク ちいたん

ちいたんとは世界最軽量のPHP用MVCフレームワーク

だそうです。
コードを見てみました。なるほど〜。ただ素のままだとフレームワーク上のエントリポイントがないので設定ファイルの読み込みを各アクションファイルに書かないといけないので煩わしいし、DRYじゃないですね。

はい、エントリポイントを追加してみた方がいらっしゃるみたいです。ソースも公開しているみたいですね。
ちいたん カスタム① フロントコントローラ化その他

ちいたんはかなり勉強になるんじゃないでしょうか。よい感じだと思います。たぶんかなり参考にするか、ほぼ流用していく気がします。

 
PHPで(M)VCフレームワーク自作
ルーティング処理だけの例ですね。

 
[memovie] 自作フレームワークについてとフォームからのPOST
これは勉強になる!素晴らしすぎではないでしょうか。参考にします。

PHP Webフレームワークを自作するサイトです。(@^^@)
んっ?全体さらってみたけど、これで読んだら今回の趣旨完結してしまわないか?
そのくらい俊逸サイトかも。

自作フレームワークをgithubへ公開
(くわ、そろそろ疲れてきた。寝よう。)あとでソース読ませて頂きます。

CakePHP内の処理を理解する
参考になるかな。とりあえず載せておきます。

軽量なMVCフレームワークの自作(改訂版)
セッション管理、永続オブジェクトの保持の概念など勉強になりました。

CakePHPの何か
おまけくらいに。古いバージョンのが今よりも軽量だろうから参考になるかも?

速構Web Framework
あとで読まさせて頂きます。

よし、Google先生に聞くのはこの辺でおしまいと。作りながら、上記のサイトだったり、有名どこのフレームワークを参考にやっていこうと思います。
 
最後にどんなフレームワークを作りたいか、というか最低限どの点を抑えていくか挙げていきたいと思います。
・MVCパターン
・エントリポイントのティスパッチャでコントローラー、モデル、ビューを振り分ける。
・コントローラー、モデル、ビューはフォルダ毎に分かれる構成。
・セッション管理
・データベース接続管理

とりあえず以上のものを目指します。

ではでは。

第50回PHP勉強会に行った

  • 2010-02-28 (日)
  • PHP

第50回PHP勉強会に参加したので、そのエントリ。

発表は三つあって、
1. mixiアプリについて(Weboo!)
2. PHPでWEB開発を行うようにしてオープンソーシャルアプリを作る(KuniTsuji)
3. 運用した気になるモバイルオープンソーシャル (個々一番)

1. mixiアプリについて(Weboo!)

  • ユーザ属性
  • だいたい20代以前半。ちょっと女性

  • アプリ嗜好性
  • mixi:ソーシャルグラフ(リアルなともだちと)
    gree:バーチャルグラフ(見ず知らずな人)

  • ユーザアクティブ数
  • ログインユーザ:1189 →1257
    滞在時:2:40→ 3:42
    pV:150.6→ 270

  • PCでは、OpenSocial Javascript API。モバイルでは、OpenSocial Restful Protocol。
  • 最新阪のOAuthにはバグがある
  • $request->to_header();

    引数に以下みたいなものを指定する
    $reqeust->to_header( apimixipralform);(たぶん間違ってます)

  • どんアプリがヒットするか?
  • ・友人と一緒に遊べないアプリは流行らない
    ・分かりやすさが大事
    ・ほとんど友人からの招待でアプリを始める
    ・友達と一緒にプレイしている空気感
    ・巻き込み感→友人に紹介したくなる
    ・継続性→変化がある→更新情報など
    ・初期はアプリはゲームと勘違いされていたが、結局長くプレイされるのはコニュニケーション性が強いアプリ

  • モバイルの開発もPCからアクセス可能な静的ファイルを配信可能なサーバも準備中
  • 3/16にDeNA技術セミナーがあります

 
所感:アプリを作成する上でコミュニケートするという部分がミソだよということを伝えたかったように思われます。人間の心理を利用したもの、飽きられないものが人気を出す秘訣ではないかなと感じました。

2. PHPでWEB開発を行うようにしてオープンソーシャルアプリを作る(KuniTsuji)

  • webサービスをそのままmixiアプリに移植することができないか?
  • モバイルは可能そうだが、PCはできなそう。

  • CodeIgnighterを利用してやってみた。
  • ・通常のaタグと、formタグは利用できない。それを吸収する処理を利用した。(anchor(),form_openなどの関数を作成)
    ・セッションの処理、oauthの処理を隠蔽

  • その他処理
  • 1.gadgets.util.registerOnLoadHandler(init)でVIEWER,OWNER,アプリ情報を取得
    2. gedgets.io.makeRequest
    3. gadgets.views.requestNavigateTo(supportedViews[view].params)で遷移処理

 
所感:既存にあるサービスをそのままオープンソーシャル対応にする試みは大変ファンキーなものです。ぜひ汎用化できたら是非オープン化してほしいものです(笑)

3. 運用した気になるモバイルオープンソーシャル (個々一番)

  • PCとモバイルの違い
  • 絵文字
    javascriptが使えない
    会社間契約が必要

  • 公式・勝手サイトの違い
  • 携帯識別番号が必要ない
    opensocailの仕組み上で認証する

  • 注意点(opensocialに限らず)
  • 外部のAPIは信用しない
    ・返事が帰ってこない
    ・バグだってあるさ

  • ちょっとしたヒント
  • PHPでAuthorzationヘッダとれないよ
    Basic認証とかはパースして置き換えてるよ
    apache_request_headersを使うとよい

  • ゆるふわコーディング
  • エラーが出ました画面より、mixiと繋がりませんみたいな画面を出したほうがよい

  • インフラ・パフォーマンス
  • 画像生成をキュー処理に書き換え
    画像サーバを外部に→AmazonS3
    サーバ間に間に合わないので一部の機能をEC2へ。現在は使ってない
    memcacged適用範囲を増やす
    L7ロードバランサを増やす
    DBマスター分割

    結局いいサーバかったら(100万しないくらい)問題の部分は解決した

所感:インフラの戦いは人気が出たらマストです。結局性能の高いサーバを購入したら悩んでいたことが解決したっていうのは、お金がある時分はいいのですけど、最初はなかなかアプローチできないことかもしれませんね。やはりウノウさんが試したようにできることのなかで最善のパフォーマンスを出すことが必須なような気が致します。その過程を発表して頂いて勉強になりました。ありがとうございます。

最後に会場を提供して頂いた株式会社コンテンツワン川井様、並びにスピーカー、運営して頂いた方々ありがとうございました。

ではでは。

【TIPS】配列の中に指定した要素が含まれているかチェック

  • 2010-02-01 (月)
  • PHP

PHPの関数の中にありそうで以外にない表題を満たす関数。
in_arrayがあるけど、階層が一つでも深くなると期待した動作をしない。
なので、何階層もある配列の中身を再帰的にチェックする関数が欲しいところですね。

ではコードです。

   /**
    * 配列の中に指定した要素が含まれているかチェック
    *
    * @param value チェックしたい文字列
    * @param array チェックしたい配列
    *
    * @return boolean 存在していれば true / 存在していなければ false
    */
   public function recursive_in_array($value, $array) {
     foreach($array as $item) {
       if(!is_array($item)) {
         if ($item == $value) return true;
         else continue;
       }

       if(in_array($value, $item)) return true;
       else if(self::recursive_in_array($value, $item)) return true;
     }
     return false;
   }

同じ動作を期待しても、コーディング内容って違いますよね。
google先生に聞いて見ると、以下の処理を見つけました。

    protected function recursive_in_array($needle, $haystack)
    {
        foreach ($haystack as $stalk) {
            if ($needle === $stalk || (is_array($stalk) &amp;&amp; recursive_in_array($needle, $stalk))) {
                return true;
            }
        }
        return false;
    }

なるほど。すべて一行にまとめられるのか。

勉強になります。

ではでは

超初級者から脱出するためのPHP関数10

  • 2009-08-20 (木)
  • PHP
    ぜひぜひ使いこなしたい関数10個です。

  1. array_merge() - ひとつまたは複数の配列をマージする
  2. $array1 = array("color" => "red", 2, 4);
    $array2 = array("a", "b", "color" => "green", "shape" => "trapezoid", 4);
    $result = array_merge($array1, $array2);
    print_r($result);
    //Array
    //(
    //   [color] => green
    //    [0] => 2
    //    [1] => 4
    //    [2] => a
    //    [3] => b
    //    [shape] => trapezoid
    //    [4] => 4
    //)
    
  3. array_fill() - 配列を指定した値で埋める
  4. $a = array_fill(5, 6, 'banana');
    $b = array_fill(-2, 2, 'pear');
    print_r($a);
    print_r($b);
    //Array
    //(
    //    [5]  => banana
    //    [6]  => banana
    //    [7]  => banana
    //    [8]  => banana
    //    [9]  => banana
    //    [10] => banana
    //)
    //Array
    //(
    //    [-2] => pear
    //    [0] => pear
    //)
    
  5. array_diff() - 配列の差を計算する
  6. $array1 = array("a" => "green", "red", "blue", "red");
    $array2 = array("b" => "green", "yellow", "red");
    $result = array_diff($array1, $array2);
    
    print_r($result);
    //Array
    //(
    //    [1] => blue
    //)
    
  7. array_pad() - 指定長、指定した値で配列を埋める
  8. $input = array(12, 10, 9);
    
    $result = array_pad($input, 5, 0);
    // 結果は、array(12, 10, 9, 0, 0) です。
    
    $result = array_pad($input, -7, -1);
    // 結果は、array(-1, -1, -1, -1, 12, 10, 9) です。
    
    $result = array_pad($input, 2, "noop");
    // 埋める処理は行われません。
    
  9. array_slice() - 配列の一部を展開する
  10. $input = array("a", "b", "c", "d", "e");
    
    $output = array_slice($input, 2);      // "c", "d", "e" を返す
    $output = array_slice($input, -2, 1);  // "d" を返す
    $output = array_slice($input, 0, 3);   // "a", "b", "c" を返す
    
    // 配列キーの違いに注意
    print_r(array_slice($input, 2, -1));
    print_r(array_slice($input, 2, -1, true));
    //Array
    //(
    //    [0] => c
    //    [1] => d
    //)
    //Array
    //(
    //    [2] => c
    //    [3] => d
    //)
    
  11. list() - 配列と同様の形式で、複数の変数への代入を行う
  12. 詳しくはマニュアルへ

  13. extract()-配列からシンボルテーブルに変数をインポートする
  14. /* $var_array はwddx_deserializeから返された配列と仮定します */
    
    $size = "large";
    $var_array = array("color" => "blue",
                       "size"  => "medium",
                       "shape" => "sphere");
    extract($var_array, EXTR_PREFIX_SAME, "wddx");
    
    echo "$color, $size, $shape, $wddx_size\n";
    # blue, large, sphere, medium
    
  15. compact() - 変数名とその値から配列を作成する
  16. $city  = "San Francisco";
    $state = "CA";
    $event = "SIGGRAPH";
    
    $location_vars = array("city", "state");
    
    $result = compact("event", "nothing_here", $location_vars);
    print_r($result);
    //Array
    //(
    //    [event] => SIGGRAPH
    //    [city] => San Francisco
    //    [state] => CA
    //)
    
  17. strpos() - 文字列が最初に現れる場所を見つける
  18. 詳しくはマニュアルへ

  19. func_get_args() - 関数の引数リストを配列として返す
  20. function foo()
    {
        $numargs = func_num_args();
        echo "引数の数: $numargs<br />\n";
        if ($numargs >= 2) {
            echo "二番目の引数は: " . func_get_arg(1) . " です。<br />\n";
        }
        $arg_list = func_get_args();
        for ($i = 0; $i < $numargs; $i++) {
            echo "引数 $i は: " . $arg_list[$i] . " です。<br />\n";
        }
    }
    
    foo(1, 2, 3);
    // 引数の数: 3<br />
    // 二番目の引数は: 2です。<br />
    // 引数 0 は: です。<br />
    // 引数 1 は: です。<br />
    // 引数 2 は: です。<br />
    

    以上を使いこなせる技術があれば超初級者の出口は見える!かも。

    ただ大事なのは、コーディングの最中読み易い処理になるにはどうしたらいいのかを意識することでしょう。
    そして、今実装している処理が猥雑だなと思ったら「自分がどういう処理がしたいかを明確にして」リファレンスまたはネットから関数を探す作業をする。そのほうが、関数を丸暗記するより気が楽な気がします。

    ではでは

連続する半角文字列を改行する方法を学ぶ

  • 2009-04-03 (金)
  • PHP


長いURLや連続する半角文字列が改行されないことは、Webサービスを開発したことがある人なら誰もが経験したことがあるかもしれません。
私も何度か経験したことがあり、なにかしろの対策で対応してきました。

ここでまたこの件に触れましたので、今回学んだことを書き留めます。

対策方法を検索して調べてみるとCSSや <wbr>を使用することが書かれていますね。

今回学んだことは「半角の空白文字を文字列の中に挿入することで改行」を実現する処理でした。

テンプレートに出力する際、半角の空白文字を挿入する処理をしています。smartyで実現しています。

以下がsmarty内での変換を実現している処理です。仮に名前はmodifier.NewLine.phpとします
IE、Firefox、Google Chromeで正常に動作確認しました。使用する場合は、自己責任でお願いします。

/**
 * URL(および切れ目のない半角文字列)折り返し
 *
 * @param  $str    対象文字列
 * @param  $limit  長さ
 * @param  $encode エンコード
 * @param  $ins    挿入文字
 * @return  $ret  変換後の文字列
 */

// 折り返しの代わりにデフォルトで半角スペースを入れる+
function smarty_modifier_ NewLine($str, $limit, $encode = 'utf-8', $ins = " ")
{

    $str = htmlspecialchars_decode($str, ENT_QUOTES);//htmlspecialchars() の反対です。 特殊な HTML エンティティを文字に戻します。
    if ($str == '' || $limit <= 0) {
        return '';
    }

    mb_regex_encoding($encode);//カレントの正規表現用のエンコーディングを文字列として返す

    $ret = '';
    $c = 0;
    $i = 0;
    $len = mb_strlen($str);//文字エンコーディング encoding の文字列 str の文字数を返します。 マルチバイト文字の一文字は1個として数えられます。

    while (true) {
        if ($i >= $len) {//文字列の長さを超えたら終了
            break;
        }
        if ($limit <= $c) {//文字列´の長さが指定した長さを超えたら、スペースを挿入。カウントを0に戻す。
            $ret .= $ins;
            $c = 0;
        }
        $data = mb_substr($str, $i, 1);//文字列から一文字だけ取得
        if ($data == '{') {//絵文字の始まりか?
            $tmp = mb_substr($str, $i, $len - $i, 'utf-8');//文字列からスタートiから文字列最後までを取得
            if (preg_match('/{emoji=([a-z0-9, ]+)}/i', $tmp, $res)) {//取得した文字列が絵文字の正規表現と一致すれば$resに格納
                $ret .= $res[0];
                $c += 2;//絵文字は2文字分?
                $i += mb_strlen($res[0]);
                continue;
            }
        }
        if ($data == "\r") {//
        } else if ($data == "\n") {//改行文字ならば\rをつけた改行にする?
            $ret .= "\r\n";
            $c = 0;
        } else {
            $ret .= $data;
            if ($data == " " || $data == " ") {
                // 半角スペースか全角スペースに当たったらカウンターをリセット
                $c = 0;
            } else {
                $c += mb_strwidth($data);//文字列の幅を返す。マルチバイト文字は通常シングルバイト文字の倍の幅となります。
            }
        }
        $i++;
    }
    $ret = htmlspecialchars($ret, ENT_QUOTES);//特殊文字をHTMLエンティティに変換する。例、'<' (小なり) は '<'

    return $ret;
}

以下が、テンプレートでの使用例です。


{$form.hoge|Newline:"100"|}

Home > PHP Archive

Search
Feeds
Meta

Return to page top