Web システムのツボの最近のブログ記事

Web システムのツボ

[Facebook API] FQLについて

201202032149.jpg


Facebook APIには、SQLに似たFQL(Facebook Query Language)という機能が備わっています。 SQLと似たインターフェースで、SQL感覚でデータを扱うことが出来ます。 自身の名前や友達リストなど基本的な情報を取得する場合、標準のGraph APIで事足りるのですが、より細かな情報を取得する場合にFQLはとても便利です。

FQLリファレンスはこちらを参考にしてください。
https://developers.facebook.com/docs/reference/fql/

また、FQLは公式のテストコンソールを使用して確認する事が出来ます。
https://developers.facebook.com/docs/reference/rest/fql.query/

試しに、いくつか検索してみた例を紹介します。

1.日本語表記の名前を取得

 Facebookで名前を取得しようとした時に、日本語表記と英語表記が混ざっていること無いですか?
 日本語表記の人は、出来れば日本語で表示したいですよね。
 Facebookには、名前の設定にその国の言語表記も設定することが出来ます。
 そこに母国語の名前を設定しているユーザは、このFQLで母国語の表記を取得することが出来ます。
 ※「user」テーブルではなく「profile」テーブルを指定します。
 SELECT name FROM profile WHERE id = me()

2.友人の中で、女性のみを抽出

 特に用途は不明ですが、何かの案件で調べたことがあったので紹介します。
 このように、サブクエリも使用することが出来ます。
 SELECT name, sex FROM user WHERE uid IN (SELECT uid2 FROM friend WHERE uid1 = me()) AND sex IN ('female')

3.友達の中で、このアプリ(FQLを実行するアプリ)を使っていない人を取得

 例えば、友達の中でこのアプリを使っていない人に対して招待する場合などに、
 対象ユーザのリストが作成できますね。

 SELECT name, sex FROM user WHERE uid IN (SELECT uid2 FROM friend WHERE uid1 = [YOUR_APP_ID]) AND is_app_user IN ('1')

4.自分が「いいね!」を押したFacebookページのURLとファン数を取得

 過去に「いいね!」を押したページを取得することが出来ます。
 「いいね!」を取り消したい場合に一覧で取得できると便利ですね。

 SELECT page_id, name, fan_count, page_url FROM page WHERE page_id IN (SELECT uid, page_id FROM page_fan WHERE uid = me()) ORDER BY fan_count

5.Facebookにログイン中の友達リストを取得

   SELECT uid FROM user WHERE online_presence IN ('active', 'idle') AND uid IN (SELECT uid2 FROM friend WHERE uid1 = me())

取得できる情報を知っておく事で、アプリ制作の幅も広がると思います。 Facebookを使っていて、まだまだ情報を整理できていない部分、不便に思うこともあると思います。 そういった機能を補助する形でアプリを作っていくと、面白いものが出来るかもしれませんね。


(tsubasa)
Web システムのツボ

SSI(Server Side Include)で外部ファイルを読み込んでみよう

「htmlファイルで外部ファイルやPHPファイルを読み込みたい!」

という時はSSIを利用すれば簡単に実現できます。
今回はその方法を紹介したいと思います。

ただし、セキュリティの問題がありますので、
実案件で使用する際には、リスクを説明した上でお客様に確認をとってください。
更に、サーバーでSSIが使用できるかのチェックも忘れずに!

以上の事を注意してSSIを行ってみましょう。

ApacheでSSIを使えるようにする

まずSSIを行うには、Apacheの設定でSSIが許可されている必要がありますが、
最初から許可設定になっているサーバは少ないと思います。
そこで、SSIを有効にする為に.htaccessファイルに下記を記入します。
(残念ながらhtaccessが許可されていないサーバの場合は潔く諦めましょう)
Options +Includes
AddHandler server-parsed html
1行目がSSIを使えるようにする記述、
2行目は拡張子がhtmlのファイルにSSIを有効にする記述です。

上記の記述を行い、SSIを有効にしたい一番上の階層のディレクトリに
「.htaccess」ファイルをアップロードします。
execを有効にしない場合
上記の設定ですと、「exec」のプログラム実行も有効となります。
SSIを利用する目的が、 「execを使用してCGIプログラムを呼び出さない」
「ヘッダやフッタのhtmlを読み込むだけでOK!」 というような場合は、1行目を下記に書き換えます。
Options +IncludesNOEXEC
NOEXECをつける事によって、「exec」の機能を省くことができます。
拡張子がshtmlのファイルのみSSIを有効にしたい場合
2行目を下記の記述に変更して下さい。
AddHandler server-parsed shtml
これで、shtmlの拡張子ファイルのみSSIが有効になり、 htmlの拡張子ファイルではSSIが無効となります。


htmlファイルにコードを記述

次に外部ファイルを読み込むコードを記述します。
Googleなどで検索してみると、だいたい下記の方法がヒットすると思います。
<!--#include file="Include.html" -->
<!--#include virtual="../include/Include.html" -->
この「file=""」「virtual=""」の違いは、
読み込むファイルのディレクトリ場所によって記述方法が変わります。

「file」
は、 上層のディレクトリにあるファイルは読み込めません。
<!--#include file="../file/oooo.html" -->
これだとエラーになります。 下記のように、同ディレクトリやサブフォルダにある場合はOKです。
<!--#include file="oooo.html" -->
<!--#include file="file/oooo.html" -->
反対に、「virtual=""」の場合は、
別のディレクトリ指定でも、サーバの絶対パスでも指定が可能です。 下記の様な記述でもOKです。
<!--#include virtual="../file/oooo.html" -->
<!--#include virtual="/file/oooo.html" -->
上記の記述を外部ファイルを読み込みたい箇所に書いておくと、
外部ファイルの中身と置き換わります。
後はブラウザで確認し、上手く動作していればSSIの実装完了です!

他にもSSIでできることはたくさんあるのですが、
今回は外部ファイルの読み込みをご紹介させていただきました。
こんなに便利なSSIですが、冒頭でも書きました通りセキュリティの問題があるので、
十分ご注意下さい。


(hirohito)
Web システムのツボ

htaccessでPC,モバイル,スマートフォンサイトの振り分け

スマートフォンの普及により、PC、モバイル、スマートフォンと3種類のサイトを作成する案件が増えてきました。
そこで、htaccessを使用して各サイトへ振り分けする方法をご紹介します。

例では、
/     ・・・ドキュメントルートをPCサイト
/mb/ ・・・モバイルサイト
/sm/ ・・・スマートフォンサイト
とします。

振り分けの流れは、このようになります。

<モバイルサイトにアクセスがあった場合>
1.スマートフォンでアクセスがあると、「mb」フォルダパスを「sm」に置き換える
2.モバイル以外からアクセスがある(PCからアクセスがある)と、「mb」フォルダパスを削除

<スマートフォンサイトにアクセスがあった場合>
3.モバイルからアクセスがあると、「sm」フォルダパスを「mb」に置き換える
4.スマホとモバイル以外からアクセスがある(PCからアクセスがある)と、「mb」フォルダパスを削除

<PCサイトにアクセスがあった場合>
5.モバイルからアクセスがあると、「mb」フォルダパスを付与する
6.スマートフォンからアクセスがあると、「sm」フォルダパスを付与する


<htaccessの記述>
RewriteEngine On
RewriteBase / # 1.No enter except MOBILE(SMART)
RewriteCond %{REQUEST_URI} ^/mb/
RewriteCond %{HTTP_USER_AGENT} ^.*(iPhone|iPod|Android).*$
RewriteRule ^mb(.*)$ sm$1 [R]
# 2.No enter except MOBILE(PC)
RewriteCond %{REQUEST_URI} ^/mb/
RewriteCond %{HTTP_USER_AGENT} !^(DoCoMo|J-PHONE|KDDI|DDIPOKET|UP\.Browser|J-PHONE|Vodafone|SoftBank).*$
RewriteRule ^mb(.*)$ $1 [R]
# 3.No enter except SMART(MOBILE)
RewriteCond %{REQUEST_URI} ^/sm/
RewriteCond %{HTTP_USER_AGENT} ^(DoCoMo|J-PHONE|KDDI|DDIPOKET|UP\.Browser|J-PHONE|Vodafone|SoftBank).*$
RewriteRule ^sm(.*)$ mb$1 [R]
# 4.No enter except SMART(PC)
RewriteCond %{REQUEST_URI} ^/sm/
RewriteCond %{HTTP_USER_AGENT} !^(DoCoMo|J-PHONE|KDDI|DDIPOKET|UP\.Browser|J-PHONE|Vodafone|SoftBank|.*iPhone|.*iPod|.*Android).*$
RewriteRule ^sm(.*)$ $1 [R]
# 5.No enter except PC(MOBILE)
RewriteCond %{REQUEST_URI} !^/mb/
RewriteCond %{REQUEST_URI} !^/sm/
RewriteCond %{HTTP_USER_AGENT} ^(DoCoMo|J-PHONE|KDDI|DDIPOKET|UP\.Browser|J-PHONE|Vodafone|SoftBank).*$
RewriteRule ^(.*)$ mb/$1 [R]
# 6.No enter except PC(SMART)
RewriteCond %{REQUEST_URI} !^/mb/
RewriteCond %{REQUEST_URI} !^/sm/
RewriteCond %{HTTP_USER_AGENT} ^.*(iPhone|iPod|Android).*$
RewriteRule ^(.*)$ sm/$1 [R]

一度振り分け方法を知っておけば後は使い回しが出来ますね。
ちなみに、過去の案件で会員登録をPC、モバイル、スマートフォンの3種類で出来るページを作成しましたが、
頻繁に使用されているのは、PC > スマートフォン > モバイル だったそうです。
やはり、モバイルサイトでの登録はかなり根気が要りますね。


(tsubasa)
開発日誌 Web システムのツボ

【Android】FacebookAPIをアプリに組み込む

FacebookボタンがあるAndroidアプリをよく見かけると思いますが、その組込み方の紹介をしたいと思います。
今回は、Facebook認証からウォール投稿できるまでの処理を組み込んでいきます。
設置の流れとしては、以下の流れとなります。


(1)Facebook-sdk-androidのダウンロード(ライブラリのダウンロード)
(2)Eclipseでライブラリプロジェクトの作成
(3)Androidアプリプロジェクトの生成
(4)FacebookにAndroidアプリを登録
(5)ソースの組込


(1)Facebook-sdk-androidのダウンロード(ライブラリのダウンロード)

ライブラリをダウンロードページからダウンロードします。(保存先は任意の場所でいいです。)

(2)Eclipseでライブラリプロジェクトの作成

(1)のライブラリプロジェクトの作成をします。

[ファイル] > [新規] > [Androidプロジェクト]を実行

facebook2.png facebook3.png facebook4.png

(3)Androidアプリプロジェクトの生成

EclipseでFacebookのAPIを使うAndroidアプリを作成してください。
[ファイル] > [新規] > [Androidプロジェクト] を実行します。


作成出来たら(2)で作成したライブラリを読み込ませます。
[プロジェクト右クリック] > [プロパティ] > [Android] を実行。
ライブラリーの追加ボタンを押して、(2)のライブラリを選択してください。
facebook5.png facebook6.png facebook7.png

(4)FacebookにAndroidアプリを登録

Facebookにアプリを登録します。 アプリ登録ページからアプリを登録します。
1 Create New App選択
2 App名登録
facebook8.png
3 必要情報を登録(特にデフォルトで何も変更しなくてもよいです。APPIDを控えておく)
facebook9.png

(5)ソースの組込

1 AndroidManifest.xmlに次のソースを組みこむ
の前に下記ソースを組みこむ
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
2 FacebookのアプリにKey Hashを記入する

●デバッグキーハッシュを確認する

[ウィンドウ(W)] > [設定] > [Android(ビルド) ]を実行。
「デフォルト・デバッグ・キーストア」の箇所を確認。控えておきます。facebook10.png ●コマンドプロンプトを立ち上げて、以下のキーを起動

        keytool -exportcert -alias androiddebugkey -keystore "上記のデバッグキーハッシュパス" | openssl sha1 -binary | openssl base64
        
・パスワードを聞かれるので「android」と入力
→Key Hashが返されます。 facebook12.png ●(4)で登録したアプリのキーハッシュを登録 facebook11.png

Activityファイルのサンプルコード

Activityファイルのサンプルは以下の通りです。
      package face.gp;
      
      import com.facebook.android.AsyncFacebookRunner;
      import com.facebook.android.DialogError;
      import com.facebook.android.Facebook;
      import com.facebook.android.FacebookError;
      import com.facebook.android.Facebook.DialogListener;
      
      import android.app.Activity;
      import android.content.Intent;
      import android.content.SharedPreferences;
      import android.os.Bundle;
      import android.preference.PreferenceManager;
      import android.util.Log;
      import android.widget.Toast;
      
      public class Facetest2Activity extends Activity {
      
      Facebook facebook = new Facebook("アプリID"); // Facebookアプリの登録されたIDを入れる
      AsyncFacebookRunner masync = new AsyncFacebookRunner(facebook);
      
      private int mAuthAttempts = 0;
      private String mFacebookToken;
      
      /** Called when the activity is first created. */
      @Override
      public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
      auth();	// 認証
      }
      
      /*
      * セッションの保存
      */
      private void saveFBToken(String token, long tokenExpires){
      SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
      prefs.edit().putString("FacebookToken", token).commit();
      }
      
      
      /*
      * 認証部分
      */
      private void fbAuthAndPost(){
      if(mFacebookToken.equals("")){
      facebook.authorize(this, new String[]{"publish_stream"}, new DialogListener() {
      
      @Override
      public void onComplete(Bundle values) {
      Log.d(this.getClass().getName(),"Facebook.authorize Complete: ");
      saveFBToken(facebook.getAccessToken(), facebook.getAccessExpires());
      updateStatus(values.getString(Facebook.TOKEN));
      }
      
      @Override
      public void onFacebookError(FacebookError error) {
      Log.d(this.getClass().getName(),"Facebook.authorize Error: "+error.toString());
      }
      
      @Override
      public void onError(DialogError e) {
      Log.d(this.getClass().getName(),"Facebook.authorize DialogError: "+e.toString());
      }
      
      @Override
      public void onCancel() {
      Log.d(this.getClass().getName(),"Facebook authorization canceled");
      }
      });
      }
      }
      
      @Override
      protected void onActivityResult(int requestCode, int resultCode,Intent data) {
      super.onActivityResult(requestCode, resultCode, data);
      switch (requestCode){
      case Facebook.DEFAULT_AUTH_ACTIVITY_CODE:
      facebook.authorizeCallback(requestCode, resultCode, data);
      }
      }
      
      /*
      * 最初に動く処理
      */
      private void auth(){
      
      mAuthAttempts = 0;
      
      SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
      mFacebookToken = prefs.getString("FacebookToken", "");
      
      if(mFacebookToken.equals("")){
      fbAuthAndPost();
      }else{
      updateStatus(mFacebookToken);
      }
      
      }
      
      /*
      * ウォール投稿を表示する処理
      * 
      */
      public void updateStatus(String accessToken){  
      
      /************
      * ウォールに投稿
      ************/
      Bundle bundle = new Bundle();
      
      bundle.putString("message", "");
      bundle.putString("link", "URL");
      bundle.putString("name", "テスト");
      bundle.putString("caption", "キャプション");
      bundle.putString("picture", "<img URL>");	
      bundle.putString("description", "アプリ説明");
      
      /* Facebookダイアログ表示 */
      facebook.dialog(Facetest2Activity.this, "feed", bundle, new DialogListener() {
      
      public void onComplete(Bundle values) {   
      
      }
      
      public void onFacebookError(FacebookError e) {
      }
      
      public void onError(DialogError e) {
      }
      
      public void onCancel() {
      }
      });    	
      } 
      }
      
      
各関数の説明
saveFBToken関数
セッションを保存する関数。Facebookにログインした時からセッションを保存する関数
fbAuthAndPost関数
認証部分。ここでFacebookのOAuth認証を行う。
onActivityResult関数
Facebook処理が終わった後に動く関数。
auth関数
FacebookのAccess Tokenを調べてなかったらfbAuthAndPost関数呼び出しFacebook認証画面へ。
updateStatus関数
認証後にウォール投稿のデフォルト設定する関数。デフォルト設定に使うメソッド。
ウォール投稿部分のソースの説明
bundle.putString("link", "リンクURL");
bundle.putString("name", "題名");
bundle.putString("caption", "キャプション名");
bundle.putString("picture", img URL);	
bundle.putString("description", "説明");
link・・・リンク付け
name・・・アプリ名前
caption・・・アプリ名前の直下に出る部分
picture・・・アプリのアイコン画像(ファイルパスはURLで設定)
description・・・アイコンの説明
サンプルコード
上記のコードをダウンロードできます。
ダウンロード:facetest2.zip

(kozo)
Web システムのツボ

Adobe Edge のプレビュー版 を使ってみました

edge_title.jpg FlashからJavaScriptへ移行する動きが盛んになってきています。
そんな中2011年08月01日、AdobeからHTML5 デザインツール Adobe Edge の
プレビュー版が公開されました。

今回インストールする環境はWindowsです。
インストールするには、Windows Vista以上が最低限必要になります。
僕自身Flash案件を担当することが多かったのですが、
Adobe Edgeを使用してどのようなものが作れるのかを試してみました。

ダウンロード

Adobe Edge Preview版
※Adobe Edge Preview版をダウンロードするには、アカウント登録をする必要があります。

サンプル

まず始めに、「Adobe Labs」にサンプルがありますので、どのようなものが出来るかご覧ください。

1.Getting Jumpy
20110821_sample1.jpg

2.Sunshine and Sailing
20110821_sample2.jpg

3.Ferris Wheel and Roller Coaster
20110821_sample3.jpg

4.Solar System
20110821_sample4.jpg

5.Planet Earth
20110821_sample5.jpg

6.Time Clock
20110821_sample6.jpg

どれもパッと見た限りではFlashかJavascriptか見分けがつかない程の出来栄えです。
サンプル版とソースは下記からダウンロードできます。
Adobe Edge Preview Sample Files


Adobe Edge を使ってみた

早速プレビュー版をダウンロードして簡単なものを作ってみました。
今回作るものは、よくあるサイトトップの画像が切り替わるフラッシュと同じものです。

1.起動画面
起動するとこのような画面が立ち上がります。
edge_sample1.jpg

2.新しくプロジェクトを作成します
普段FlashはFlash CS4で制作を行っていますが、各操作方法は違和感なく使うことが出来ました。
現在はプレビュー版なので触れるプロパティに限りがありますが、それでも十分いいものが作れそうです。

・プロパティ
edge_sample3.jpg

・エレメント
edge_sample4.jpg

・タイムライン
edge_sample5.jpg


3.画像追加
今回は画像を切り替えるものを作るので、 [File]=>[Import]から画像をステージに追加します。
edge_sample6.jpg

4.イベント追加
一通り画像を配置し終わると、プロパティとタイムラインを操作してイベントを追加していきます。
イージングも一通り用意されており、細かく設定することが出来ます。
edge_sample7.jpg


5.完成

デモを見てみる
edge_201108221427.jpg

Flashを作るような感覚で、すごく楽に作ることが出来ました。
書き出したJSファイルも割りと整理されている印象を受けました。
これらのファイルを直接編集することも十分出来そうです。
Adobe Edgeの今後の動向に注目です。

ちなみに、HTML5なのでIEをどうするかは悩みどころですね。

(tsubasa)

オープンソース紹介 Web システムのツボ

郵便番号APIを使った住所自動入力フォーム

今回は実際に郵便番号検索APIを使ったサンプルソースをご紹介します。使用する言語はPHPです。
メールフォーム等でよく使う、郵便番号から住所を自動入力してくれるように組んでいきます。
今回作成したソースはダウンロードできます。

ダウンロード:sample.zip

下記に、メイン関数の処理を記述します。
function main(){

	// 初期処理
	$inputData = getData();

	// 検索ボタン押された場合
	if(isset($inputData['search'])){

		//入力情報GET
		$inputData = getData();

		//入力内容チェック
		$error = check ($inputData);

		if ($error['flg']){
			//エラー表示
			disp($inputData,$error);
			return;
		}

		//郵便番号APIのURLを設定
	  	$url = 'http://zip.cgis.biz/xml/zip.php?zn='.$inputData['zipnum1'].$inputData['zipnum2'];

	    //郵便番号APIから入力された郵便番号の情報を取得
	    $xmlData  =file_get_contents($url);
	    $xmlParser = xml_parser_create();
	    xml_parse_into_struct($xmlParser,$xmlData,$addressData);
	    xml_parser_free($xmlParser);

	    //取得データをセット
	    $setData = setData($addressData,$inputData);

	    //セットされたデータをチェック
	    $error = check($setData);

		if ($error['flg']){
			//エラー表示
			disp($setData,$error);
			return;
		}

		disp($setData);
	}else{
		disp($inputData);
	}

}
【ブラウザ表示】
API2.jpg

使用方法を説明させて頂きます。
入力項目の住所検索ボタンを押すと郵便番号APIを呼び出し、
取得したxmlファイルのデータを各入力項目に代入させています。
ブラウザ表示の処理はdisp関数で行っております。
disp関数の引数は郵便番号APIから取得したデータの配列で、htmlを生成させて表示しています。
また、郵便番号APIを使用する際の規約について、
画面のどこかにリンクを貼り付けることになっていますので、
今回は画面の下方に「利用しているAPI 郵便番号API」と表示させています。

郵便番号APIを呼び出す時は以下のようにしています。

//郵便番号APIのURLを設定
$url = "http://zip.cgis.biz/xml/zip.php?zn=".$inputData["zipnum1"].$inputData["zipnum2"];
//郵便番号APIから入力された郵便番号の情報を取得
$xmlData  =file_get_contents($url);

変数の「$inputData["zipnum1"]」や「$inputData["zipnum2"]」においては、getData関数で指定していります。
getData関数ではサーバーにpostで送信した郵便番号と各入力項目を配列で設定しています。
getData関数の配列のキーは以下の通りです。

設定フラグ:flg
郵便番号1:zipnum1
郵便番号2:zipnum2
都道府県:state
都道府県カナ:state_kana
市区町村:city
市区町村カナ:city_kana
住所:address
住所カナ:address_kana
番地:company
番地カナ:company_kana

取得したxmlファイルのデータを配列に置き換えている処理は以下のソースで処理しています。
	    $xmlParser = xml_parser_create();
	    xml_parse_into_struct($xmlParser,$xmlData,$addressData);
	    xml_parser_free($xmlParser);
	    //取得データをセット
	    $setData = setData($addressData);
上記のsetData関数で取得したxmlファイルを各データに配列でセットしています。
入力された郵便番号のデータがない場合、setData関数で設定フラグを「false」にし、check関数でエラーを表示するように設定しています。
郵便番号setData関数の内訳は以下の通りになります。

設定フラグ:flg
郵便番号1:zipnum1
郵便番号2:zipnum2
都道府県:state
都道府県カナ:state_kana
市区町村:city
市区町村カナ:city_kana
住所:address
住所カナ:address_kana
番地:company
番地カナ:company_kana

check関数では、以下のチェック処理をしております。

データの有無:入力された郵便番号のデータチェック
郵便番号1:郵便番号桁数チェック(3桁)+数字チェック
郵便番号2:郵便番号桁数チェック(4桁)+数字チェック

上記チェック処理に当てはまった場合はエラーメッセージを表示するようにしております。
ダウンロードして頂いて、試しに使っていただいたら非常に嬉しい限りです。

参照URL
郵便番号API:郵便番号APIのページへ
XML処理:WEBシステム開発の情報サイト


(kozo)
Web システムのツボ

Flash CS4でフォントを変更してコードを見やすくする方法

Flash CS4 でデフォルトのスクリプトフォントは、「MS UI Gothic」となっています(Windows)。
このフォントは等幅ではないので、コードが見づらくなります。


例えば、エディタで綺麗に記述していたコードをCS4に貼り付けた場合、
整列がばらばらになったりします。

そこで、環境設定でフォントを変えるとこのような問題はなくなります。


1.メニューバーの「編集」=>「環境設定」を選択
20110322_01.jpg


2.カテゴリ「ActionScript」のフォントを「_等幅」に変更
20110322_02.jpg


これで、整列されたコードを記述できます。


デフォルトの「MS UI Gothic」フォントの場合
20110322_03.jpg

「_等幅」に変更した場合
20110322_04.jpg


デフォルトのままだと、カンマやドットといった文字を見落としてしまう場合があるので、

変更しておくことをオススメします。


(tsubasa)

Web システムのツボ

PHPの画像リサイズを、配布されているクラスで実現してみよう(PHP5+GDライブラリ必須)

ブログ等でよく紹介されているクラスですが、
細かい解説サイトなどがなかったので、こちらで紹介してみようと思います。
(誤りや訂正等ございましたら情報をお寄せ下さい)


今回使用してみるクラスはこちらです。

【PHP Image Resezer Class】
http://www.milaju.com/post/php-image-resizer-class

PHP+GDライブラリを使用し、画像変換の処理をかんたんに行ってくれるクラスです。


上記サイトから圧縮ファイルをダウンロードし、
解凍をすると下記のようなディレクトリ構成になっています。

 

ディレクトリ構成.gif


index.phpを開いてみましょう。


下記のPHPスクリプトに注目です。

 

index_php.gif


上から順に見てみますと、
最初にクラスファイルを読み込み、
その後に「$imgSizer->」で画像リサイズの詳細設定をしています。


各項目設定の内容を下記に簡単にご紹介します。


$imgSizer->type = "width";
画像をリサイズする縦横の基本設定を行います。
設定できるタイプは、「width」と「height」です。


$imgSizer->max = 100;
リサイズするピクセルサイズを指定します。
$imgSizer->type = "width"の場合、幅が100ピクセル
"height"の場合は高さが100ピクセルになります。


$imgSizer->quality = 8;
画質の調整が行えます。
1〜10までの設定が可能です。
数字が高ければ画質が高くなります。


$imgSizer->square    = true;
画像のリサイズ方法に関する設定です。
設定できる値は、「true」と「false」です。
true:画像の中心を基本とし、正方形で画像をリサイズする。
false:縦横の比率を維持してリサイズする。


$imgSizer->prefix    = "sml_";
リサイズした画像名の先頭に付加する名称を指定できます。
例:元画像が「test.jpg」→リサイズ後「sml_test.jpg」


$imgSizer->folder    = "_sized/";
リサイズした画像を保存するディレクトリを指定します。
デフォルトでは、リサイズ元の画像と同階層のディレクトリにフォルダが作成されます。


以上が基本の設定になります。


そして、最後にリサイズ元の画像を設定します。
$imgSizer->image     = "/PHP_ImageSizer/images/test.jpg";
デフォルトの状態では画像のパス指定は、ルートパス指定になります。


各設定が完了しましたら、
$imgSizer->resize()」を実行します。


実行後は、リサイズされた画像のパスが返ってきます。
この値を、「<img>」タグに設定すると画像が表示できます。


PHPの記述最後の部分は、画像を配列変数に登録し、
それぞれ画像のリサイズ処理をして出力している。
というスクリプトになります。


次にclassファイルの方も少し見てみましょう。

下記の部分ですが、


resize実行.gif


この記述により「index.php」で設定した項目を、
分解・結合等を行い、最後に画像リサイズ処理を行っています。


$_SERVER['DOCUMENT_ROOT']で、パス指定を行っていますので、
ドキュメントルートの指定を外したい場合は、
この部分を修正し、カスタマイズ等を行うと、
自分の仕様で画像処理スクリプトを作成する事が可能です。


簡単な説明になりましたが以上になります。


今回紹介させて頂きましたクラス以外にも、
画像リサイズ処理は数多く配布されていると思いますので、
いろいろ試してみて、自分にあったスクリプトを見つけるのもいいかもしれないです。

その他のライブラリ
Image Resizing Made Easy with PHP 
target="_blank"Icebeat | class.image

 

 (hirohito)

Web システムのツボ

【AS3】 addEventListenerに引数を渡す

複数のオブジェクトにイベントを追加する場合、イベント発生時の処理で
どのオブジェクトか識別したい場合があります。

例えば、多数あるボタンにクリックイベントを纏めて登録する場合、

【一括でイベントを登録するサンプル
// ボタン格納配列
var btn_array:Array = new Array(btn1_mc, btn2_mc, btn3_mc, ...);

for(var i:int=0; i<btn_array.length; i++){
    // マウスイベント登録
    btn_array[i].addEventListener(MouseEvent.CLICK, onMouseClickHandler);
}

/**
 * マウスイベント
 */
function onMouseClickHandler(e:MouseEvent):void
{
    var btn_mc:MovieClip = MovieClip(e.target);
    // "btn_mc"って、btn_array配列のどのボタンが押された?
}

登録イベント発生時に、どのボタン押されたのか判別できません。
nameプロパティで出来なくはないですが、出来れば配列で回したいですよね。

この場合は、ムービークリップに対してイベントを張っているので、
予め識別できるidなどプロパティを追加しておけば楽に判別できます。

【ムービークリップに識別idを追加するサンプル
for(var i:int=0; i<btn_array.length; i++){
    // 識別id追加
    btn_array[i]._id = i;
    // マウスイベント登録
    btn_array[i].addEventListener(MouseEvent.CLICK, onMouseClickHandler);
}

/**
 * マウスイベント
 */
function onMouseClickHandler(e:MouseEvent):void
{
    // btn_array[e.target._id] が押されました!
}


というように、予め識別できるidなどを追加しておけば判別出来ます。

ただ、全てこのような形で出来るわけではなく、例えば画像読み込みに使用するloaderには、
プロパティを追加できません。

【プロパティを追加できないサンプル
// 画像ファイル名格納配列
var img_array:Array = new Array('img1.jpg', 'img2.jpg', 'img3.jpg', ...);

for(var i:int=0; i<img_array.length; i++){
    var myLoader:Loader = new Loader();
    myLoader._id = i;    // プロパティを追加できない、※エラー
    myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteHandler );
    // 読み込み開始
    myLoader.load(new URLRequest(img_array[i]));
}

/**
 * 読み込み完了イベント
 */
function onCompleteHandler(e:Event):void
{
    // どの画像が読み込み完了した?
}


そこで、loaderなどのイベント発生時に引数を渡す方法をご紹介します。

そもそもaddEventListenerの構文は、addEventListener(イベント名、リスナー関数);
となっています。
一番簡単な方法は、このリスナー関数にループで使用しているカウンタ(i)を渡してあげれば
済む話なのですが、リスナー関数の引数はリファレンスにも書かれている通り、

この関数は、次の例のように、Event オブジェクトを唯一のパラメータとして受け取り、
何も返さないものである必要があります。
function(evt:Event):void
引用:ActionScript 3.0 コンポーネントリファレンスガイド
http://livedocs.adobe.com/flash/9.0_jp/ActionScriptLangRefV3/flash/events/EventDispatcher.html

となっています。つまり、

/**
 * リスナー関数
 */
function(e:Event):void
{
    
}

という形でないといけないのです。これではループカウンタを渡すことが出来ません。
そこで、リスナー関数の構文を守り、かつループカウンタを渡す方法はこのようになります。

【AddEventListenerに引数を渡すサンプル
for(var i:int=0; i<img_array.length; i++){
    var myLoader:Loader = new Loader();
    myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteHandler(i));
    
    // 読み込み開始
    myLoader.load(new URLRequest(img_array[i]));
}

/**
   * 読み込み完了イベント
   */
function onCompleteHandler(_num:int):Function
{
    // img_array[_num] 画像が読み込み完了しました!
    
    return function(e:Event):void;
}



パラメータを受け取る関数(onCompleteHandler)を間に挟み、且つ構文を守る為
Event型を唯一の引数とした戻り値なしの関数をリターンしてあげれば完了です。

(tsubasa)
 
Web システムのツボ

Google Analytics 携帯版(PHP)のレポートがうまくとれない場合の対処法

公式にGoogleAnalytics携帯版が発表されてから大分経ちますが、
Twitterなどでも「計測できない!」とつぶやかれる方が多く目立ってました。
僕自身、担当した案件でモバイルサイトへGoogleAnalyticsを設置する機会があり
多くの方がつまづかれているのと同様にしばらく悩みました。

現象としては、タグ埋め込みもga.phpも正しく設置して1pxのgif画像も表示されているのに
「トラッキングコードが見つかりません」というエラーが表示されるというものです。
同じような現象を克服された方はいないかいろいろ調べた結果、原因がようやく分かりました。

原因はphp側の設定でした。
具体的にはga.phpで使用されているstream_context_createというPHPの関数が
php.iniのallow_url_fopenという設定がOffだと動作しないためのようです。
Onに変更後、Apacheを再起動したら無事Google Analytics携帯版で解析が可能になりました。

php.iniを修正できないサーバの場合で .htaccess で設定可能な場合は以下のように記述します。
----------------------------------------------------------
php_flag allow_url_fopen on
----------------------------------------------------------

もし設定が完璧なのに「トラッキングコードが見つかりません」というエラーが出続けている
場合はphp.iniのallow_url_fopenの設定がOnかどうかを確認してみると解消されるかもしれません。

問題解決に際して下記2つのサイトを参考にさせていただきました。
『ウェブマスターセントラル -Google Analytics 携帯版のレポートがとれません- 』
『元Webエンジニアの無職日記 -google analyticsのモバイル版の解析が上手くいかない場合の対処法 その2-』


(masato)
1  2

Webシステムのツボとは

オープンソースの紹介や、プログラミング講座、フリーソフトのレビューなど、Webエンジニアが送る、つれづれ日記。
【隔週金曜日更新】

運営会社:株式会社ジーピーオンライン

RSSを購読する

Monthly Archive