目次


Ajax と Smarty

第 1 回 Smarty を使って Ajax アプリケーションを開発する

PHP、Smarty テンプレート・エンジン、そして jQuery フレームワークを使用した Ajax アプリケーションの構築

Comments

コンテンツシリーズ

このコンテンツは全#シリーズのパート#です: Ajax と Smarty

このシリーズの続きに乞うご期待。

このコンテンツはシリーズの一部分です:Ajax と Smarty

このシリーズの続きに乞うご期待。

この連載の第 1 回目では、Smarty テンプレートを使用して Ajax リクエストに対するレスポンスを JSON、XML、および HTML で生成する方法を学びます。ここで説明する手法を使うと、PHP コードを開発する際にアプリケーション・ロジックの開発に専念できるようになります。それは、アプリケーション・ロジックが、Ajax クライアントとサーバーとの間の通信に使用するデータ・フォーマットから切り離されるためです。

レスポンスの生成方法に続いて説明するのは、2 つのバージョンを持つ 1 つのフォームを作成する方法です。一方のバージョンではユーザーが入力フィールドにデータを入力できるようにし、もう一方のバージョンでは隠しフィールドを使って編集できないようにデータを表示します。ユーザーがボタンをクリックするとフォームのバージョンが切り替わり、Ajax でデータをサーバーに送信して、ページの更新に必要な HTML コンテンツを取得することができます。さらに、このフォームは Web ブラウザーで JavaScript が無効にされているとしても機能します。

記事の最後のセクションでは、Smarty とサンプル・アプリケーションを構成する際の手順を説明します。このプロセスは、お使いのサーバーまたはワークステーションで SELinux が有効に設定されている場合には多少複雑になります。けれども SELinux が提供する高度なセキュリティーを考えれば、追加コマンドを実行しなければならないとしても、それはわずかな代償です。ここで提供する情報は、コンテンツ管理システム (CMS) などの、公開ファイルを変更する必要のある Web アプリケーションや、ユーザーがコンテンツをアップロードできるようにしている Web サイトに役立ちます。Smarty、よく使われている CMS、あるいはカスタマイズしたシステムのどれを使用するとしても、コードで Web ファイルを変更しようとすると、すぐさま SELinux に関連した共通の構成問題に突き当たるはずです。この記事では、この問題を Linux® の restoreconchcon、および setsebool コマンドを使用して解決する方法を紹介します。

Smarty による Ajax レスポンスの生成

このセクションでは、Ajax リクエストへのレスポンスを生成する Smarty テンプレートの作成方法を学びます。使用するフォーマットは、JSON、XML、HTML など、一般的なものであればどれでも可能です。Smarty の構文は主に HTML を対象に設計されているため、Smarty は XML にも非常に適しています。一方、Smarty で JSON レスポンスを作成するとなると若干ややこしくなります。テンプレートの構成要素はその構文の中で {} を使用することから、この 2 つの文字を JSON で使用するには文字をエスケープしなければならないためです。けれども後で一例を記載するように、Smarty の区切り文字を変更すれば、この構文上の競合を防ぐことができます。このセクションではまた、テンプレートでカスタムの修飾子および関数を使えるように、Smarty フレームワークに登録する修飾子、関数を作成する方法も説明します。

Smarty で XML 文書を生成する場合

最初に、Ajax クライアントが使用できる XML レスポンスを生成する、単純なサンプル (リスト 1 を参照) から取り掛かります。この PHP コードにまず初めに必要なのは、コンテンツ・タイプと no-cache ヘッダーを設定することです。コンテンツ・タイプと no-cache ヘッダーを設定しておけば、Web ブラウザーは Ajax レスポンスをキャッシュしません。Smarty をこれまで使用したことのない方のために、この demo_xml.php ファイルの実行内容を簡単に説明しておくと、このファイルは require 文によって Smarty クラスを組み込み、このクラスの新しいインスタンスを作成した後、インスタンスのコンパイル・フラグとデバッグ・フラグを設定します。続いて assign() によって root_attr および elem_data という 2 つの変数を作成し、display() を使って demo_xml.tpl という名前の Smarty テンプレートを呼び出します。その結果、XML レスポンスが生成されます。

リスト 1. サンプル demo_xml.php
<?php
header("Content-Type: text/xml");
header("Cache-Control: no-cache");
header("Pragma: no-cache");

require 'libs/Smarty.class.php';

$smarty = new Smarty;

$smarty->compile_check = true;
$smarty->debugging = false;
$smarty->force_compile = 1;

$smarty->assign("root_attr", "< abc & def >");
$smarty->assign('elem_data', array("111", "222", "333"));

$smarty->display('demo_xml.tpl');

?>

demo_xml.tpl テンプレート (リスト 2 を参照) が生成する <root> 要素には、demo_xml.php ファイルで作成された root_attr 変数の値を属性値として持つ属性があります。<>"'& の文字は、Smarty の escape 修飾子を使って、それぞれ &lt;&gt;&quot;&apos;&amp; に置き換えられます。root 要素内では、テンプレートが Smarty の {section} 関数を使用して elem_data 配列 (demo_xml.php ファイルで割り当てられている 2 番目の変数) の要素を繰り返し処理します。配列に含まれる要素ごとに、demo_xml.tpl テンプレートは配列から取得した値を含めた XML 要素を生成します。

リスト 2. demo_xml.tpl テンプレート
<root attr="{$root_attr|escape}">
    {section name="d" loop=$elem_data}
        <elem>{$elem_data[d]|escape}</elem>
    {/section}
</root>

リスト 3 に、demo_xml.php ファイルと demo_xml.tpl テンプレートによって生成された XML 出力を記載します。

リスト 3. XML 出力
<root attr="&lt; abc &amp; def &gt;">
            <elem>111</elem>
            <elem>222</elem>
            <elem>333</elem>
</root>

Smarty で JSON レスポンスを生成する場合

demo_json.php ファイル (リスト 4 を参照) では、リスト 3 と同じく no-cache ヘッダーを設定して Smarty オブジェクトを作成、構成している他、さらに PHP の json_encode() を呼び出す json_modifier()json_function() という関数を定義しています。この 2 つの関数は、テンプレートで使用できるように Smarty に登録します (このセクションの後で説明)。関数の登録に続いて demo_json.php ファイルが作成しているのは、それぞれに異なる型 (文字列、数値、ブール、および配列) を持つ Smarty 変数です。そして最後に、このサンプル PHP コードは demo_json.tpl テンプレートを実行して JSON レスポンスを生成します。

リスト 4. サンプル demo_json.php
<?php
header("Content-Type: application/json");
header("Cache-Control: no-cache");
header("Pragma: no-cache");

require 'libs/Smarty.class.php';

$smarty = new Smarty;

$smarty->compile_check = true;
$smarty->debugging = false;
$smarty->force_compile = 1;

function json_modifier($value) {
    return json_encode($value);
}

function json_function($params, &$smarty) {
    return json_encode($params);
}

$smarty->register_modifier('json', 'json_modifier');
$smarty->register_function('json', 'json_function');

$smarty->assign('str', "a\"b\"c");
$smarty->assign('num', 123);
$smarty->assign('bool', false);
$smarty->assign('arr', array(1,2,3));

$smarty->display('demo_json.tpl');

?>

プラグイン (修飾子や関数など) を Smarty に登録する代わりに、Smarty マニュアル (「参考文献」を参照) で説明している特殊な命名規則に従うという方法もあります。この命名規則に従ったコードを plug-ins ディレクトリーに配置すれば、Smarty 修飾子と関数をアプリケーションのあらゆる Web ページで使用できるようになります。

JSON と Smarty はどちらも構文の中で {} を使用するため、JSON レスポンスに含まれる { および } 文字を生成するには、Smarty テンプレートで {ldelim} および {rdelim} を使用しなければなりません。{literal}{/literal} の間であれば {} を配置することも可能ですが、別のサンプルで説明するように、Smarty の区切り文字を変更すれば、この厄介な作業は不要になります。

demo_json.tpl テンプレート (リスト 5 を参照) は、demo_json.php ファイルに設定された 4 つの変数の値をエンコードするために、json 修飾子を使用します。この修飾子は例えば、引用符や他の特殊文字 (文字列に含まれるタブや改行など) をエスケープするのに便利です。Smarty は、テンプレートが |json を使うたびに、demo_json.php ファイルの json_modifier() 関数を呼び出します。json 修飾子の前には @ 文字を追加して、array 変数を json_modifier() に渡せるようにしてください。@ 文字がないと、配列の要素ごとに json_modifier() 関数が呼び出されることになってしまいます。

demo_json.tpl テンプレートの {json ... } 構成要素は、demo_json.php ファイルの json_function() の呼び出しに変換されます。この関数はテンプレートの属性を params という名前の配列として取得し、この配列を json_encode() に渡します。するとこの関数が、PHP 連想配列の JSON 表現を返します。

リスト 5. demo_json.tpl テンプレート
{ldelim}
	s: {$str|json},
	n: {$num|json},
	b: {$bool|json},
	a: {$arr|@json},
	o: {json os=$str on=$num ob=$bool oa=$arr},
	z: {literal}{ x: 1, y: 2 }{/literal}
{rdelim}

リスト 6 に、demo_json.php ファイルと demo_json.tpl テンプレートによって生成された JSON 出力を記載します。

リスト 6. JSON 出力
{
	s: "a\"b\"c",
	n: 123,
	b: false,
	a: [1,2,3],
	o: {"os":"a\"b\"c","on":123,"ob":false,"oa":[1,2,3]},
	z: { x: 1, y: 2 }
}

Smarty テンプレートで {ldelim}{rdelim} を使わなくても済むようにするには、リスト 7 に示すように Smarty 区切り文字を変更することができます。

リスト 7. Smarty 区切り文字の変更
$smarty->left_delimiter = '<%';
$smarty->right_delimiter = '%>';

リスト 8 に記載するテンプレートは、Smarty 構成要素で <% および %> を区切り文字として使用して JSON レスポンスを生成します。

リスト 8. demo_json2.tpl テンプレート
{
	s: <% $str|json %>,
	n: <% $num|json %>,
	b: <% $bool|json %>,
	a: <% $arr|@json %>,
	o: <% json os=$str on=$num ob=$bool oa=$arr %>,
	z: {  x: 1, y: 2 }
}

Smarty による Ajax ページの作成

このセクションでは、Smarty を使用して、Ajax で取得される HTML コンテンツを生成する例を説明します。さらに、この Web ページにある HTML フォームのデータは、Ajax でサーバーに送信されます。そのために使用しているのが、jQuery フレームワークです。JavaScript が Web ブラウザーで無効に設定されていても、このフォームは正常に機能し、サーバー上でコンテンンツを生成するのにも引き続き Smarty が使用されます。

HTML フォームで Smarty を使用する場合

demo_form.tpl テンプレート (リスト 9 を参照) に含まれる HTML フォームには、edit_mode という変数の値によって編集できるかどうかが決まるフィールドがあります。この変数は、このセクションの後でわかるように、テンプレートを呼び出す PHP コードで設定されます。edit_mode の値は、フォームの隠しフィールドにも保管されます。

リスト 9. demo_form.tpl テンプレートの HTML フォーム
<form method="POST" name="demo_form">

<input type="hidden" name="edit_mode" 
    value="{if $edit_mode}true{else}false{/if}">

<table border="0" cellpadding="5" cellspacing="0">
    ...
</table>

</form>

リスト 10 に、フォームの最初のフィールドを記載します。このフィールドは、edit_modetrue の場合には入力ボックスとなり、edit_modefalse の場合には隠しフィールドとなります。後者の場合、出力には値を編集することのできないフィールド {$smarty.post.demo_text|escape} が組み込まれます。ユーザーが編集可能なフォームを送信するときには、ユーザーの入力は demo_text パラメーターに含まれることになります。フォームが編集できない場合でも、隠しフィールドのおかげで、このパラメーターは維持されます。そのため、フォームが編集可能であってもなくても、$smarty.post.demo_text によって post パラメーターの値を取得することができます。

リスト 10. demo_form.tpl テンプレートのテキスト・フィールド
    <tr>
        <td>Demo Text:</td>
        <td>
            {if $edit_mode}
                <input type="text" name="demo_text" size="20"
                    value="{$smarty.post.demo_text|escape}">
            {else}
                <input type="hidden" name="demo_text" 
                    value="{$smarty.post.demo_text|escape}">
                {$smarty.post.demo_text|escape}
            {/if}
        </td>
    </tr>

フォームの 2 つ目の入力フィールドはチェック・ボックスです (リスト 11 を参照)。編集可能なバージョンのフォームでは、demo_checkbox パラメーターが存在する場合にのみ、input 要素に checked 属性が含まれます。同様に、編集可能でないバージョンのフォームには、送信されたフォーム・データに demo_checkbox という POST パラメーターが含まれる場合にのみ、隠しフォーム要素が含まれます。

リスト 11. demo_form.tpl テンプレートのチェック・ボックス
    <tr>
        <td>Demo Checkbox:</td>
        <td>
            {if $edit_mode}
                <input type="checkbox" name="demo_checkbox" 
                    {if $smarty.post.demo_checkbox}checked{/if}>
            {else}
                {if $smarty.post.demo_checkbox}
                    <input type="hidden" name="demo_checkbox" value="On">
                {/if}
                {if $smarty.post.demo_checkbox}On{else}Off{/if}
            {/if}
        </td>
    </tr>

フォームが表示する以下の表の行には、3 つのラジオ・ボタンがあります (リスト 12 を参照)。テンプレートのコードは各ボタンの値を demo_radioパラメーターと比較して、どのラジオ・ボタンを選択するべきかを決定します。編集可能でないバージョンのフォームは、隠し入力フィールドを使ってパラメーターの値を保管し、その値を $smarty.post.demo_radio によってユーザーに表示します。

リスト 12. demo_form.tpl テンプレートのラジオ・ボタン
    <tr>
        <td>Demo Radio:</td>
        <td>
            {if $edit_mode}
                <input type="radio" name="demo_radio" value="1"
                    {if $smarty.post.demo_radio == '1'}checked{/if}>1
                <input type="radio" name="demo_radio" value="2"
                    {if $smarty.post.demo_radio == '2'}checked{/if}>2
                <input type="radio" name="demo_radio" value="3"
                    {if $smarty.post.demo_radio == '3'}checked{/if}>3
            {else}
                <input type="hidden" name="demo_radio" 
                    value="{$smarty.post.demo_radio|escape}">
                {$smarty.post.demo_radio|escape}
            {/if}
        </td>
    </tr>

フォーム・リストの選択肢は、{section} によるループの中で生成されます (リスト 13 を参照)。ループの現行のインデックスが demo_counter というテンプレート変数に割り当てられた後、この変数と、その選択肢が選択されたかどうかを判断するために生成される、選択肢の要素の値とが比較されます。

リスト 13. demo_form.tpl テンプレートのリスト
    <tr>
        <td>Demo Select:</td>
        <td>
            {if $edit_mode}
                <select name="demo_select" size="1">
                    {section name="demo_section" start=10 loop=100 step="10"}
                        {assign var="demo_counter"
                            value=$smarty.section.demo_section.index}
                        <option {if $smarty.post.demo_select == $demo_counter}
                                selected{/if} value="{$demo_counter}">
                            {$demo_counter}
                        </option>
                    {/section}
                </select>
            {else}
                <input type="hidden" name="demo_select" 
                    value="{$smarty.post.demo_select|escape}">
                {$smarty.post.demo_select|escape}
            {/if}
        </td>
    </tr>

edit_mode フラグの値によって、送信ボタンには異なるラベル (「Save (保存)」または「Edit (編集)」) が設定されます (リスト 14 を参照)。このボタンの onclick 属性に含まれるのは、submitDemoForm() という JavaScript 関数の呼び出しです。後で詳しく説明しますが、この関数は Ajax を使用してフォームのデータをサーバーに送信した後に false を返します。そのため、Web ブラウザーがボタンのクリックに対するレスポンスとして同じデータを何度も送信することがありません。けれども JavaScript が無効に設定されている場合には、submitDemoForm() は呼び出されずに、Web ブラウザーがフォームをサーバーに送信します。したがって、JavaScript が有効に設定されていようと、無効に設定されていようと関係なく、このフォームは適切に機能します。

リスト 14. demo_form.tpl テンプレートの送信ボタン
    <tr>
        <td>&nbsp;</td>
        <td>
            <button type="submit" onclick="return submitDemoForm()">
                {if $edit_mode}Save{else}Edit{/if}
            </button>
        </td>
    </tr>

ページ・テンプレートを開発する

demo_page.tpl ファイル (リスト 15 を参照) には、2 つの <script> 要素があります。1 つは jQuery 用、もう 1 つはサンプル・アプリケーションのJavaScript ファイル用です。このページ・テンプレートは Smarty の {include} 関数を使って、<div> 要素内にフォーム・テンプレートをインクルードします。

リスト 15. demo_page.tpl テンプレート
<html>
<head>
    <title>Demo</title>
    <script type="text/javascript" 
        src="//ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js">
    </script>
    <script type="text/javascript" src="demo_js.js">
    </script>
</head>
<body>
    <div id="demo_div">
        {include file="demo_form.tpl"}
    </div>
</body>
</html>

Smarty と Ajax に対応した PHP コントローラーを作成する

Ajax と Smarty との間の架け橋として機能する demo_html.php ファイル (リスト 16 を参照) では、Ajax リクエストを処理し、Ajax ヘッダーが存在する場合にだけ呼び出される demo_form.tpl テンプレートを使って Ajax レスポンスを生成するために、Smarty を使用します。Ajax ヘッダーは、次のサブセクションで説明するように JavaScript コードに設定されます。このコードは、Ajax ヘッダーがない場合には demo_page.tpl テンプレートを使用します。Ajax ヘッダーがないということは、これが Web ブラウザーから送信される最初のページ・リクエストであるか、そうでなければ JavaScript が無効に設定されていることを意味します。各リクエストの処理の後に、edit_mode フラグの値はもう一方の値に設定されて、フォームの編集可能バージョンと編集不可バージョンの切り替えが行われます。

リスト 16. サンプル demo_html.php
<?php
header("Cache-Control: no-cache");
header("Pragma: no-cache");

require 'libs/Smarty.class.php';

$smarty = new Smarty;

$smarty->compile_check = true;
$smarty->debugging = false;
$smarty->force_compile = 1;

$edit_mode = @($_REQUEST['edit_mode'] == "true");
$smarty->assign("edit_mode", !$edit_mode);

$ajax_request = @($_SERVER["HTTP_AJAX_REQUEST"] == "true");
$smarty->display($ajax_request ? 'demo_form.tpl' : 'demo_page.tpl');

?>

Ajax を使用して Smarty テンプレートを呼び出す

submitDemoForm() 関数 (リスト 17 を参照) は、フォームのボタンがクリックされると呼び出されます。この関数は jQuery を使ってフォームのデータをサーバーに送信します。その際に使用するメソッドは POST、そして Web フォームで使用する URL と同じ URL です。フォームのデータは jQuery の serialize() API を使って文字列としてエンコードされます。このサンプルでは、Ajax リクエストを送信する前に jQuery が呼び出す beforeSend() 関数を使用して、サーバー・サイドで Ajax リクエストを識別するために必要な Ajax-Request ヘッダーを設定しています。Ajax レスポンスを受信すると、success() 関数が呼び出され、このコールバックによってレスポンスに含まれるコンテンツが Web ページの <div> 要素に挿入されます。

リスト 17. サンプル demo_js.js
function submitDemoForm() {
    var form = $("form[name=demo_form]");
    $.ajax({
        type: "POST",
        url: form.action ? form.action : document.URL,
        data: $(form).serialize(),
        dataType: "text",
        beforeSend: function(xhr) {
            xhr.setRequestHeader("Ajax-Request", "true");
        },
        success: function(response) {
            $("#demo_div").html(response);
        }
    });
    return false;
}

SELinux が有効に設定されている場合の Smarty のセットアップ

サンプル・アプリケーションを解凍するとわかるように、ajaxsmarty という名前のディレクトリーには PHP ファイルと JavaScript ファイルの他、サブディレクトリーとして cache、configs、templates、templates_c の 4 つがあります。サンプル・アプリケーションの Smarty テンプレートは templates ディレクトリーに格納されています。他の 3 つのサブディレクトリーには何も置かれていません。

Smarty の最新安定版リリースをダウンロードして (「参考文献」を参照)、解凍してください (このサンプル・アプリケーションは Smarty 2.6.25 でテストしました)。続いて、解凍後の Smarty の libs サブディレクトリーを、サンプル・アプリケーションのメイン・ディレクトリーである ajaxsmarty ディレクトリーにコピーします。

ajaxsmarty ディレクトリー (サンプル・アプリケーションと Smarty の libs ディレクトリーが含まれている状態) を、Apache の html ディレクトリーにアップロードまたはコピーします。サーバーとして Web のホスティング会社を利用している場合、サポートを求める電話が殺到する原因となりかねないことから、SELinux は無効に設定されていると思いますが、アプリケーションを独自の Linux システムでテストする場合には、おそらく SELinux は有効に設定されているはずです。この場合、ブラウザーから PHP ファイルをリクエストすると、「SELinux is preventing the httpd from using potentially mislabeled files (SELinux では、httpd は誤ったラベルが付けられている可能性のあるファイルを使用できません)」というエラーを受け取ることになります。このエラーを解決するには、root として、リスト 18 に記載するコードを実行します。

リスト 18. Web ファイルのセキュリティー・コンテキスト (ラベル) の設定
restorecon -R -v /var/www/html/ajaxsmarty

上記のコマンドを実行した時点で、ブラウザーで http://localhost/ajaxsmarty/ を開けるようになるはずです。ここには、3 つのリンクが提示されているので、いずれかのリンクをクリックしてみてください。すると、Web ブラウザーに「Fatal error: Smarty error: unable to write to $compile_dir '/var/www/html/ajaxsmarty/templates_c'. Be sure $compile_dir is writable by the Web server user. in /var/www/html/ajaxsmarty/libs/Smarty.class.php on line 1113」という Smarty エラーが表示されます。このエラーは、$compile_dir '/var/www/html/ajaxsmarty/templates_c' への書き込み操作を実行できないため、/var/www/html/ajaxsmarty/libs/Smarty.class.php の 1113 行目で、 $compile_dir is writable が Web サーバーのユーザーに対して書き込み可能に設定されていることを確認するように伝えています。

このエラーが発生した理由は、Smarty のセットアップがまだ完了していないからです。Web サーバー・ユーザーには、templates_c および cache ディレクトリーへの書き込み許可を与えなければなりません。そのための正しい方法は、リスト 19 に記載するように、この 2 つのディレクトリーの所有者を変更することです。お使いのコンピューターでは、apache のユーザー名およびサーバーの html ディレクトリーは異なる場合があることに注意してください。

リスト 19. Smarty がディレクトリー内にファイルを作成できるように 2 つのディレクトリーの所有者を変更する
chown apache:apache /var/www/html/ajaxsmarty/templates_c 
chown apache:apache /var/www/html/ajaxsmarty/cache

root アクセス権限を持っていない場合には、chown を使用する代わりに、templates_c と cache の書き込み許可を変更するという方法もあります。書き込み許可は、FTP クライアントを使用すれば変更できるはずです。あるいは、777 パラメーターを使って chmod コマンドを実行するのでも構いません。これらのフォルダーにすべてのユーザーが書き込めるようにするのは賢明ではないかもしれませんが、chownを使用できないとしたら、これがすぐに使える唯一の方法です。Web サーバーが公開されている場合には、サーバー管理者に問い合わせてください。

上記の問題を解決しても、SELinux がコンピューター上で有効になっているとしたら、ブラウザーに「SELinux prevented httpd reading and writing access to http files (SELinux により、http ファイルへの httpd 読み取り/書き込みアクセスが拒否されました)」、または「SELinux is preventing httpd (httpd_t) write to ./templates_c (public_content_rw_t) (SELinux は、httpd (httpd_t) による ./templates_c (public_content_rw_t) への書き込みを許可していません)」というエラーが表示されることが考えられます。その場合には解決策として、root としてリスト 20 のコマンドを実行してください。

リスト 20. SELinux が有効に設定されている場合に Smarty のディレクトリー内でのファイル作成を許可する
chcon -t public_content_rw_t /var/www/html/ajaxsmarty/templates_c 
chcon -t public_content_rw_t /var/www/html/ajaxsmarty/cache
setsebool -P allow_httpd_anon_write=1

allow_httpd_anon_write パラメーターを設定した setsebool コマンドを 1 回だけ実行しなければなりません。そうすれば、httpd デーモンが public_content_rw_t というラベルが付いたディレクトリーにファイルを作成できるようになります。

まとめ

この記事では、Ajax リクエストに対する JSON、XML、HTML レスポンスを生成する Smarty テンプレートを作成する方法、Smarty を使用して、Web ブラウザーが無効になっていても機能する Ajax フォームを作成する方法、そして SELinux が有効に設定された Linux マシンで Smarty を構成する方法について説明しました。


ダウンロード可能なリソース


関連トピック


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Web development, Open source
ArticleID=503080
ArticleTitle=Ajax と Smarty: 第 1 回 Smarty を使って Ajax アプリケーションを開発する
publish-date=04272010