にゃあ

XOOPS Cubeでスライドショーを作れるプリロード JquerySlideShow

JquerySlideShow

うさできのmikaさんの投稿を読みながら、もう少し手軽にできるようになるといいなーと思って、XOOPS Cubeで簡単にスライドショーを作れるプリロードを作ってみました。急いで作ったので、結構テキトーです。なにか問題があったら教えてください。

ちなみに、どんなスライドショーができるかは、うさできのトップページを見てみてください。

インストール方法

ダウンロードした JquerySlideShow.class.php を/preloadフォルダにアップロードするだけです。

ちなみに、このファイルだけでは動作しません。jquery.jsが必要です。XCL2.2ならデフォルトで入ってます。XCL2.1の人でよく分からない人はJquery.class.phpを/preloadフォルダに入れといてください。

使い方

基本的にテーマのすきなところにタグを埋め込めこんで使います。編集するテーマのファイはたぶん/themes/あなたのテーマ/theme.htmlです。埋め込み方は下の説明を御覧ください。

[基本編] テーマで使う

画像の大きさを指定して、画像のURLを1行ずつ列挙するだけ

<{slideshow width=680 height=80}>
http://example.com/path/to/image1.png
http://example.com/path/to/image2.png
http://example.com/path/to/image3.png
<{/slideshow}>

[発展編] 画像のリンク先を指定する

画像のURLの次に、半角スペースを挟んでリンク先のURLを指定すると、画像にリンクがつきます。

<{slideshow width=680 height=80}>
http://example.com/path/to/image1.png http://example.com/page1.html
http://example.com/path/to/image2.png http://example.com/page2.html
http://example.com/path/to/image3.png http://example.com/page3.html
<{/slideshow}>

[応用編] 画像のURLに<{$xoops_url}>を使う

画像のURLに<{$xoops_url}>を使うと、サイトのURLが変わったときに、URLを書き換える必要がないので便利です

<{slideshow width=680 height=80}>
<{$xoops_url}>/uploads/myalbum/1.png <{$xoops_url}>/modules/pico/index.php?content_id=1
<{$xoops_url}>/uploads/myalbum/2.png <{$xoops_url}>/modules/pico/index.php?content_id=2
<{$xoops_url}>/uploads/myalbum/3.png <{$xoops_url}>/modules/pico/index.php?content_id=3
<{/slideshow}>
-----------------------------------------------------

[応用編] カスタムブロックで使う

カスタムブロックの「コンテンツ」に次のようなコードを埋め込みます。 カスタムブロックの「タイプ」は「PHPスクリプト」を指定します。

$params = array(
  'width' => 680, // 幅指定
  'height' => 80, // 縦指定
);
$images ="
http://example.com/path/to/image1.png
http://example.com/path/to/image2.png
http://example.com/path/to/image3.png
";
JquerySlideShow::renderSlideShow($params, $images);



[PHP]interfaceの命名規約いろいろ

PHPのinterfaceの命名規約ってどういうのがいいんだろう?Javaや他の言語の命名規則をあつめてみた。うちは、こんな命名規則でやってます、というのがあったら教えてください。

1. Iを接頭辞にする

interface IUser {}
  • ○ 慣れればインターフェイスだと比較的分かりやすいかも。
  • ○ ファイル名でソートしたときに、インターフェイスが集まる。
  • × Iが見えにくい。細い。
  • 感想: ハンガリアン記法っぽくて嫌い。

2. Interfaceを接尾辞にする

interface UserInterface {}
  • ○ インターフェイスって分かりやすい。
  • ○ もうクラスがあって、それをインターフェイスに抽象化するときは、クラス名に接尾辞つけるだけ。
  • × インターフェイス定義だけ見ると冗長。
  • × 長い。
  • 感想: 悪くないと思う。

3. -ableを接尾辞にする

interface Countable {}
  • インターフェイスは能力を表すという世界観。
  • ○ 慣れればインターフェイスって分かりやすい。
  • → クラスに-ableを使うことを禁止しないとごっちゃになる。
  • × 英語力がないとインターフェイス名考えるのが辛い。
  • 感想: なんとなくいいかも。

4. 完全に自由

interface FooBar {}
  • × クラス名とかぶるとめんどくさい。
  • × type-hintingとかuseとかinstanceofでインターフェイスって分かりにくい。
  • → 分からなくても困らないかも?
  • ○ 臨機応変に名前をつけられる。



とりあえず自分のPCからxoopscube.jpを見られるようにする方法(MacOSX)

2011/08/01現在xoopscube.jpが閲覧できなくなっています。 Google(8.8.8.8)にnslookupしてみると、解決できないじょうたいです。 推測ですが、xoopscube.jpのDNSの設定が変わったか、設定が削除されたんじゃないでしょうか。

xoopscube.jpが見れないのは不便なので、とりあえず自分のPCからだけは見られるようにする方法を紹介します。 自分がMac使いなので、Macでのやり方になります。(ここでは専用のアプリを入れますが、やっていることはhostsファイルを書き換えるだけです。Windowsにもhostsファイルがあるので同じようなことができるはずです。)

まず、Hosterというアプリをダウンロードしてください。 ダウンロードが完了したらインストールします。 インストールが終わったら起動してみましょう。起動すると下のような画面が出ます。

緑のプラスボタンをクリックします。フォームが出ると思うので、下の内容のとおりに値を入力してください。

セット名:XOOPS Cube
ホスト名:xoopscube.jp
IP: 210.143.106.113

入力が終わったら、「ホスト追加」ボタンを押してホストを追加し、「終了」でフォームを閉じます。 閉じると、「セット名」にXOOPS Cubeが追加されていると思います。

最後に、「XOOPS Cube」の左にある、グレーのまるポチをクリックします。 すると、「1件の設定をホスツファイルへ反映しました」というポップアップが表示されます。

この状態で、http://xoopscube.jp を開いてみてください。今まで通り、xoopscube.jpのサイトが見れるはずです。

なお、xoopscube.jp が復活したときは、上で追加したXOOPS Cubeセットを削除するだけです。 またHosterが起動していないときは、xoopscube.jp から 210.143.106.113へのホスティングはされないので、 xoopscube.jpを見たいときはHosterを起動するようにします。

ちなみに、xoopscube.jpのドメイン有効期間は2011/08/31までなので、ドメイン自体がなくなったわけではなさそうです。




[PHP] abstractとinterfaceの使い分けを整理してみる

abstractとinterfaceの違いを自信持って使い分けてる?

abstractとinterfaceの言語仕様はよく似てる。とても混同しやすい。PHPで自身をもって使い分けている人はどれくらいいるかな?少なくとも自分は全部abstractでもいいと思っている(いた)。でも、interfaceはオブジェクト指向できっと重要な概念だろうから、しっかり区別したいな。Twitterでオブジェクト指向に詳しそうな人に聞きいたり、ググったりして調べて自分なりに理解した内容をまとめてみるよ。

似てる点

  • そのままでは呼び出せない。abstractはextends、interfaceはimplementsしてはじめて使える。
  • 抽象メソッドを定義できる(see code.1)。ちなみにそれらは子クラスで必ず実装しないといけない。
// code.1
abstract class AbstractFoo
{
	abstract public function bar();
}

interface InterfaceFoo
{
	public function bar();
}

異なる点

  • classはabstractを1つだけextendsできるが、classはinterfaceを複数implementsできる(see code.2)。
  • abstractは具体的な実装があるメソッドを持てる。interfaceは単に抽象メソッドを列挙するだけ(see code.3)。
// code.2
class Hoge extends AbstractFoo
{
}

class Hoge implements InterfaceFoo, InterfaceFoo2, InterfaceFoo3
{
}
// code.3
abstract class AbstractFoo
{
	abstract public function bar();

	public function baz()
	{
		echo 'baz!';
	}
}

interface InterfaceFoo
{
	public function bar();
	public function baz();
}

この言語仕様を踏まえてどう使い分けるか?

「interfaceを使うくらいなら、abstract一辺倒でよくない?いざとなったらabstractに具体的な実装もできるしね」と思っている人はきっと自分だけじゃないと思う。ここではabstractじゃなくてinterfaceを使ったほうがいい、って例を説明していくよ。だから、interfaceのほうにフォーカスした内容になってる。読者はabstractの使い方をよく知っているし、よく使っているという前提ね。

仕様書はinterfaceにできるかも

interfaceは具体的な実装を持てない。これは設計書として利用できるかも知れない。今までドキュメントに書いていたクラスの仕様はinterfaceにすることができるってこと。例えば、こんな仕様書があったとする。

仕様書

  • データベースクライアントクラスは次の4つのメソッドを提供しなければなりません。
  • 書き込みメソッド。メソッド名: create()。引数は保存するデータ(連想配列)。
  • 読み込みメソッド。メソッド名: load()。引数は読み込む行のID(整数)。
  • 上書きメソッド。メソッド名: update()。引数は上書きする行のID(整数)と保存するデータ(連想配列)。
  • 削除メソッド。メソッド名: delete()。引数は削除する行のID(整数)。

文書の仕様書を否定するつもりはないけど、人の言葉で書かれた仕様書は曖昧だったりする。上の仕様書でも、戻り値がよくわかんないし、update()の引数の順番は曖昧だし、引数は必須なのか任意なのか分かんない。

紙の仕様書は、メンテナンスされないこともあるよね。仕様書がなくともプログラムは正常に動作するから。もし、仕様書がプログラムに組み込まれたらどうだろう?仕様書がメンテナンスされなければプログラムが動かないので、仕様書をメンテするようになるよね、きっと。

上の仕様書は、interfaceに翻訳することができるんだ(code.4)。下の例のほうが文書の仕様書より曖昧性が低いよね。それに、仕様変更があったときもエラーとして気が付きやすい。例えば、複数行を取得したくなって、メソッドfind(array $condition)を追加したとする。find()を実装していないサブクラスはエラーになるんだ。

// code.4
interface DatabaseClient
{
	/**
	 * テーブルに行を追加する
	 * @returns bool 保存に成功したらtrue、失敗したらfalse
	 */
	public function create(array $data);

	/**
	 * テーブルの行のデータを取得する
	 * @returns mixed 読み込みに成功したら配列、失敗したらfalse
	 */
	public function load($id);

	/**
	 * テーブルの行を更新する
	 * @returns bool 保存に成功したらtrue、失敗したらfalse
	 */
	public function update($id, array $data);

	/**
	 * テーブルの行を削除する
	 * @returns bool 削除に成功したらtrue、失敗したらfalse
	 */
	public function delete($id);
}

これはabstractでも同じような書き方ができるね。でも、具体的な実装を持たないならinterfaceにしたほうがいいかもしれないよ。interfaceは実装を持てない。これって、シンプルという長所でもあるよね。仕様を提供する側のコストがミニマムになる。それに、プログラマは最低限のリードタイムで「ここだけ実装しておけばいいのね」ということが分かるようになる。abstractだったら、そのクラスの内部実装にまで目を配らないといけないよね。つまり、interfaceのほうが設計者とプログラマの両者にとってストレスが少ないってことになるね。(ひとりで開発する場合は別かもしれないけど)

呼び出し方は同じだけど、内部の処理は全然ちがう場合はinterface

最近のウェブアプリはログインするものが多いよね。内部的なこと言ったら認証処理だね。認証処理ってのは、アプリ側が「あなたはだれ?」が特定できればよくて、それ以外の関心はない処理なんだけど、一方で、認証処理は様々なものがある。アプリ独自の認証方式、OpenID、LDAP、Basic認証、Twitter認証、Facebook認証、社内独自認証などなど。

このケースだと、interfaceを活用できる。ウェブアプリは、認証方法の詳細について口出ししない。その代わり、「interfaceに実装してほしいauthorize()っていうメソッドを定義しておいたよ。」っていう約束だけ決めて(code.5)、「うちはそれだけを呼び出すから、あとはうまいことやってね」と具体的な認証方法は各認証オブジェクトにまるなげする。

// code.5
interface Auth
{
	/**
	 * 認証処理を行う
	 * @returns bool 成功したらtrue、失敗したらfalseを返す
	 */
	public function authorize();
}

それで、各認証方式を受け持つオブジェクトは、authorize()を独自に実装する(code.6)。

// code.6
class OpenID implements Auth
{
	public function authorize()
	{
		if ( $this->_openIdAuth() )
		{
			return true;
		}

		return false;
	}

	protected function _openIdAuth()
	{
		// オープンIDで認証する処理
	}
}

この例では、abstractはほとんど役に立たないよね。だって、ウェブアプリは認証方式の詳細に口出し(具体的な実装を提供)することができないから。各認証処理は全く異なった実装になるだろうね。具体的な実装の共通化は容易じゃない。無理して共通化に心を砕くくらいなら、interfaceにしたほうがいさぎよい、と思う。

まとめ

今回、調べていて気づいた点をまとめると、interfaceの出番は次のようになる。もっと、勉強してinterfaceを上手く使えるようになりたいな。

  • 仕様書はinterfaceにできるかも
  • 呼び出し方は同じだけど、内部の処理は全然ちがう場合はinterface

参考になるページ




「WeeklyCMS 6/24 マイクロソフト本社特番03」の補足など

「WeeklyCMS 6/24 マイクロソフト本社特番03」はセキュリティ回で、ちょっと補足したほうがいいかなーと思ったんで、ブログエントリにしちゃいます。XOOPSモジュール開発しようって人に参考になればなぁと。

WeeklyCMS 6/24 マイクロソフト本社特番03

Check Secure Code (04:47〜)

$_POST/GETをforeach展開

foreach ( $_POST as $key => $value )
{
	$$key = $value;
}

「見かけたら即デリート」ということで、危険性と置き換え方がはしょられてる。時間の都合かなーと思いつつ…。

こういうコードの危険性としては、$_SERVERなどの変数を容易に乗っ取られてしまう点。置き換え方は、必要な変数だけ定義するようにすること。たとえば、下の例のように。

// title, text, posterだけがあればいいとき
$title  = $_POST['title'];
$text   = $_POST['text'];
$poster = $_POST['poster'];

intvalはエースケープ関数じゃない^^;

bluemoonさんによると、下の例がまずいらしい。

$hoge = isset($_GET['hoge']) ? $_GET['hoge'] : 0 ;

そして、整数を受け取る前提のものは、次のように書き換えるべきだとしてる

$hoge = isset($_GET['hoge']) ? intval($_GET['hoge']) : 0 ;

最初に整数にしといたほうが安全になるのは確か。HTMLに出すとき、SQLのクエリに入れるときのどちらにも対応できるから。でも、ユーザの入力を勝手に書き換えるのはあまりベストじゃない。だから、この場合は$_GETから取るときはintvalしないでおいて、HTMLに出すときにhtmlspecialchars($hoge, ENT_QUOTES, 'UTF-8')、SQLのクエリにするときにmysql_real_escape_string($hoge)しておくのがいいと思う。

htmlspecialchars()はHTMLに出す直前に

「文字列だったら、htmlspecialcharsで」とのこと。そしてそのサンプルがこれ。

$hoge = isset($_GET['hoge']) ? htmlspecialchars($_GET['hoge'], ENT_QUOTES) : "" ;

そのとおりなんだけど、$_GETから取った直後にhtmlspecialchars()をかけることはXOOPSのモジュールではほとんどない。Smartyに変数を渡す直前でやるのが通常かなと。なぜなら、リクエストをもとに何かデータをこねくり回す(DBを参照したり)ことが多いから。そのとき、HTMLエンコードされた文字列だといろいろ不便だから。なので、やっぱりこれもintval同様に$_GETから値をとった段階では生にしとく。

$hoge = isset($_GET['hoge']) ? $_GET['hoge'] : "" ;

// $hogeをもとにデータをこねくり回す処理

$hoge = htmlspecialchars($hoge, ENT_QUOTES, 'UTF-8');

$xoopsTpl->assign('hoge', $hoge); // smartyに$hogeを渡す

SQL Injection (6:01〜)

addslashes()じゃなくてmysql_real_escape_string()を使おう

録画の中でSQLインジェクションの対策として、addslashes()関数をつかうことを勧めてる。addslashes()でも、SQLのエスケープをうまくやってくれる。実際に、XOOPSのコードのいたるところにaddslashes()がある。でも、addslashes()はクエリエスケープ用の関数じゃないので、SQLインジェクション対策に使うのはちょっと意味が違う。やっぱり、ここはMySQL専用エスケープ関数のmysql_real_escape_string()を使おう。

Mac大好きなmikageさんが会場がMicrosoftなのに「PCじゃなくてMacです、PCというとWindowsです」と言っちゃってるとこを見て、ポカリふきそうになったw そのあと、Microsoftの武田さんが発表の前振りで「すいません、PCでっ」ってww6/24ほんとに行きたかったし、行けなくてもリアルタイムで放送見たかったよーT_T





Author

Submenu

Recent Entries

XOOPS Cube Dev Ring

氷川 XOOPS Module 開発室

Recent Comments

Recent Trackbacks

facebookいいね