PoiPHP サンプル集

テンプレートの基本($s の使い方)

PoiPHP のテンプレートでは、値を表示する際に $s->html()を使って HTML エスケープを行います。これは XSS 対策として必須です。

$s->html($value)
<?= $s->html($value) ?>
$s->h($value)(短縮形)
<?= $s->h($value) ?>
$s->url($value)

URL パラメータに値を埋め込むときに使用します。

<a href="detail?id=<?= $s->url($id) ?>">詳細</a>
$s->json($value)

JavaScript に PHP の値を安全に埋め込むときに使用します。

<script>
    const data = <?= $s->json($array) ?>;
</script>
    

セッション

PoiPHP のセッションは $c->sessionで扱います。 set / get / delete の 3 種類だけなので非常にシンプルです。

<?php
require_once __DIR__ . '/PoiPHP/poiphp.php';

function action(&$c)
{
    // セッションに値を保存
    $c->session->set("name", "bee");

    // セッションから値を取得
    $name = $c->session->get("name");

    // セッションの値を削除
    $c->session->delete("name");

    // テンプレートへ渡す
    $c->set("name", $name);
    $c->setTemplateFile("html/session.html");
}
                

バリデーション(実用例)

required / email / length / numeric など、必要最小限のルールで構成されています。

<?php
require_once __DIR__ . '/PoiPHP/poiphp.php';

function action(&$c)
{
    if ($c->isPost()) {

        $v = $c->validate([
            "name" => [
                "required",
                "length:3:20"
            ],
            "email" => [
                "required",
                "email"
            ],
            "age" => [
                "numeric",
                "min:18",
                "max:120"
            ],
            "password" => [
                "required",
                "length:8:50"
            ],
            "password2" => [
                "required",
                "match:password"
            ]
        ]);


        if ($v->hasError()) {
            $c->set("errors", $v->errors);
        } else {
            $c->set("ok", true);
        }
    }

    $c->setTemplateFile("html/validation.html");
}
                

バリデーションルール一覧

PoiPHP のバリデーションで使用できるルールの一覧です。

required        必須(空文字・null を禁止)
email           メール形式チェック
numeric         数値チェック
length:min:max  文字数チェック(例:length:3:20)
min:n           数値の最小値(例:min:18)
max:n           数値の最大値(例:max:120)
match:field     他のフィールドと一致(例:match:password)
custom:func     カスタム関数でチェック
    

CSRF(送信側 + 受け側チェック)

PoiPHP は POST 時に自動で CSRF チェックを行います。 不一致の場合は $c->csrfErrorが true になります。

送信側(フォーム)
<form method="post">
    <input type="hidden" name="_token" value="<?= $c->csrf ?>">
    <input type="text" name="name">
    <button>送信</button>
</form>
    
受け側(index.php)
<?php
require_once __DIR__ . '/PoiPHP/poiphp.php';

function action(&$c)
{
    if ($c->isPost()) {

        // POST の最初に必ず書く
        if ($c->csrfError) {
            return $c->error("CSRF token mismatch");
        }

        // 通常の処理
        $name = $c->post("name");
        $c->set("name", $name);
    }

    $c->setTemplateFile("html/form.html");
}
    

ファイルアップロード

ファイルアップロードは $c->upload->save() を呼ぶだけです。
ディレクトリがなければ自動で作成し、ファイル名は衝突しないようリネームして保存されます。

// 第一引数:inputのname属性、第二引数:保存先ディレクトリ
$path = $c->upload->save("photo", "uploads");
                    
if ($path) {
    // 成功:保存されたパス(例:uploads/image_1710521234.jpg)が返ります
} else {
    // 失敗:エラーまたは未選択の場合は null が返ります
}
                        

データベース接続例(SQLite / MySQL)

PoiPHP の DB 設定は PoiPHP/config.phpdatabaseセクションで行います。 PDO の DSN を書くだけのシンプルな構成です。

SQLite(最小構成・設定が最も簡単)
'database' => [
    'dsn'  => 'sqlite:' . POI_DIR . '/app.sqlite',
    'user' => null,
    'pass' => null,
],
    

SQLite はファイルを置くだけで動作します。 小規模アプリやローカル開発に最適です。

MySQL / MariaDB
'database' => [
    'dsn'  => 'mysql:host=localhost;dbname=poiphp;charset=utf8mb4',
    'user' => 'root',
    'pass' => 'password',
],
    

MySQL を使う場合は DSN / user / pass を記述します。

接続のタイミング

PoiPHP は「必要な時だけ接続」する設計です。 $c->loadModel()を呼んだ時点で初めて DB に接続します。

動作確認(最小の Model 利用例)
<?php
$User = $c->loadModel("User");
$list = $User->findAll();
$c->set("list", $list);
$c->setTemplateFile("html/user_list.html");
    

モデル(Model)

PoiPHP のモデルは「1 テーブル = 1 クラス」のシンプルな仕組みです。 必要な時だけ $c->loadModel()でロードし、 findAll / findById / insert / update / delete の基本操作が使えます。

models/User.php(モデル定義)
<?php
class User extends Model
{
    public $table = "users";   // 対応するテーブル名
}
    
モデルの読み込み(Controller)
$User = $c->loadModel("User");
    
一覧(findAll)

全件取得します。

$list = $User->findAll();
    
詳細(findById)

主キーで1件取得します。

$user = $User->findById($id);
    
追加(insert)

POST データをそのまま INSERT できます。

$User->insert([
    "name"  => $c->post("name"),
    "email" => $c->post("email")
]);
    
更新(update)

主キーを指定して UPDATE します。

$User->update($id, [
    "name"  => $c->post("name"),
    "email" => $c->post("email")
]);
    
削除(delete)

主キーを指定して DELETE します。

$User->delete($id);
    
生 SQL(query)

必要な場合は生 SQL をそのまま実行できます。

$rows = $User->query("SELECT * FROM users WHERE age > ?", [20]);
    
テンプレート側の表示例(html/user_list.html)
<h1>User List</h1>

<?php foreach ($list as $u): ?>
    <div>
        ID: <?= $s->html($u["id"]) ?>  
        名前: <?= $s->html($u["name"]) ?>
    </div>
<?php endforeach; ?>
    

CRUD(DB操作・実用コード)

PoiPHP の CRUD は「モデル + コントローラ + テンプレート」で構成されます。

1. モデル(models/User.php)

<?php
class User extends Model
{
    public $table = "users";
}
    

2. 一覧(index.php)

<?php
require_once __DIR__ . '/PoiPHP/poiphp.php';

function action(&$c)
{
    $User = $c->loadModel("User");
    $list = $User->findAll();

    $c->set("list", $list);
    $c->setTemplateFile("html/user_list.html");
}
    

3. 追加(add.php)

<?php
require_once __DIR__ . '/PoiPHP/poiphp.php';

function action(&$c)
{
    if ($c->isPost()) {

        if ($c->csrfError) {
            return $c->error("CSRF token mismatch");
        }

        $User = $c->loadModel("User");

        $User->insert([
            "name"  => $c->post("name"),
            "email" => $c->post("email")
        ]);

        return $c->redirect("index");
    }

    $c->setTemplateFile("html/user_add.html");
}
    

4. 編集(edit.php)

<?php
require_once __DIR__ . '/PoiPHP/poiphp.php';

function action(&$c)
{
    $User = $c->loadModel("User");
    $id = $c->get("id");

    if ($c->isPost()) {

        if ($c->csrfError) {
            return $c->error("CSRF token mismatch");
        }

        $User->update($id, [
            "name"  => $c->post("name"),
            "email" => $c->post("email")
        ]);

        return $c->redirect("index");
    }

    $user = $User->findById($id);
    $c->set("user", $user);
    $c->setTemplateFile("html/user_edit.html");
}
    

5. 削除(delete.php)

<?php
require_once __DIR__ . '/PoiPHP/poiphp.php';

function action(&$c)
{
    if ($c->csrfError) {
        return $c->error("CSRF token mismatch");
    }

    $User = $c->loadModel("User");
    $User->delete($c->get("id"));

    return $c->redirect("index");
}
    

6. テンプレート(html/user_list.html)

<h1>User List</h1>

<a href="add">新規追加</a>

<?php foreach ($list as $u): ?>
    <div>
        <?= $s->html($u["id"]) ?> :
        <?= $s->html($u["name"]) ?>
        <a href="edit?id=<?= $u["id"] ?>">編集</a>
        <a href="delete?id=<?= $u["id"] ?>">削除</a>
    </div>
<?php endforeach; ?>
    

7. 追加フォーム(html/user_add.html)

<h1>User Add</h1>

<form method="post">
    <input type="hidden" name="_token" value="<?= $c->csrf ?>">

    名前:<input type="text" name="name"><br>
    メール:<input type="text" name="email"><br>

    <button>登録</button>
</form>
    

8. 編集フォーム(html/user_edit.html)

<h1>User Edit</h1>

<form method="post">
    <input type="hidden" name="_token" value="<?= $c->csrf ?>">

    名前:<input type="text" name="name" value="<?= $s->html($user["name"]) ?>"><br>
    メール:<input type="text" name="email" value="<?= $s->html($user["email"]) ?>"><br>

    <button>更新</button>
</form>
    

JSON API

JSON を返す場合は $c->json()を返すだけ。

<?php
return $c->json(["status" => "ok"]);