うさできの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が変わったときに、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の命名規約ってどういうのがいいんだろう?Javaや他の言語の命名規則をあつめてみた。うちは、こんな命名規則でやってます、というのがあったら教えてください。
interface IUser {}
interface UserInterface {}
interface Countable {}
interface FooBar {}
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までなので、ドメイン自体がなくなったわけではなさそうです。
abstractとinterfaceの言語仕様はよく似てる。とても混同しやすい。PHPで自身をもって使い分けている人はどれくらいいるかな?少なくとも自分は全部abstractでもいいと思っている(いた)。でも、interfaceはオブジェクト指向できっと重要な概念だろうから、しっかり区別したいな。Twitterでオブジェクト指向に詳しそうな人に聞きいたり、ググったりして調べて自分なりに理解した内容をまとめてみるよ。
// code.1
abstract class AbstractFoo
{
abstract public function bar();
}
interface InterfaceFoo
{
public function bar();
}
// 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にすることができるってこと。例えば、こんな仕様書があったとする。
仕様書
- データベースクライアントクラスは次の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のほうが設計者とプログラマの両者にとってストレスが少ないってことになるね。(ひとりで開発する場合は別かもしれないけど)
最近のウェブアプリはログインするものが多いよね。内部的なこと言ったら認証処理だね。認証処理ってのは、アプリ側が「あなたはだれ?」が特定できればよくて、それ以外の関心はない処理なんだけど、一方で、認証処理は様々なものがある。アプリ独自の認証方式、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を上手く使えるようになりたいな。
「WeeklyCMS 6/24 マイクロソフト本社特番03」はセキュリティ回で、ちょっと補足したほうがいいかなーと思ったんで、ブログエントリにしちゃいます。XOOPSモジュール開発しようって人に参考になればなぁと。
WeeklyCMS 6/24 マイクロソフト本社特番03
foreach ( $_POST as $key => $value )
{
$$key = $value;
}
「見かけたら即デリート」ということで、危険性と置き換え方がはしょられてる。時間の都合かなーと思いつつ…。
こういうコードの危険性としては、$_SERVERなどの変数を容易に乗っ取られてしまう点。置き換え方は、必要な変数だけ定義するようにすること。たとえば、下の例のように。
// title, text, posterだけがあればいいとき $title = $_POST['title']; $text = $_POST['text']; $poster = $_POST['poster'];
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で」とのこと。そしてそのサンプルがこれ。
$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インジェクションの対策として、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
氷川 XOOPS Module 開発室