tutorial
Phalcon
未来電子

phalconのチュートリアル学習記録 -Basic編-

phalconのチュートリアルを学習してみます。

こちらを元に勉強しました。
phalconチュートリアル-Basic編-

macでxamppの上に置いてやっています

ファイル構造

xamppと一緒に使いたいので、htdocsの中にファイルを置いています。

┗ tutorial
   ┣ app
   ┇ ┣ controllers
   ┇ ┇ ┣ IndexController.php
   ┇ ┇ ┗ SignupController.php
   ┇ ┣ models
   ┇ ┇ ┗ Users.php
   ┇ ┗ views
   ┗ public
      ┣ css
      ┣ img
      ┣ js
      ┗ index.php

チュートリアルのコードの意味を徹底解明! ~「Hello」を出力するまで~

まずはindex.php

一度全体を見せたあと少しずつ解剖していきます。

public/index.php
<?php

use Phalcon\Loader; //①オートローダー使うよ!って宣言
use Phalcon\Mvc\View;  //ビューを使用するために必要な宣言
use Phalcon\Mvc\Application;  //MVCの煩雑な処理はこれが行なっているらしい
use Phalcon\Di\FactoryDefault; //Phalconに付属しているコンポーネントのほとんどを登録するための宣言
use Phalcon\Mvc\Url as UrlProvider; //URLを作成するために必要な宣言

// Define some absolute path constants to aid in locating resources
define('BASE_PATH', dirname(__DIR__)); //
define('APP_PATH', BASE_PATH . '/app');

// Register an autoloader
$loader = new Loader();

$loader->registerDirs(
    [
        APP_PATH . '/controllers/',
        APP_PATH . '/models/',
    ]
);

$loader->register();

// Create a DI
$di = new FactoryDefault();

// Setup the view component
$di->set(
    'view',
    function () {
        $view = new View();
        $view->setViewsDir(APP_PATH . '/views/');
        return $view;
    }
);

// Setup a base URI
$di->set(
    'url',
    function () {
        $url = new UrlProvider();
        $url->setBaseUri('/');
        return $url;
    }
);

$application = new Application($di);

try {
    // Handle the request
    $response = $application->handle();

    $response->send();
} catch (\Exception $e) {
    echo 'Exception: ', $e->getMessage();
}

解剖します

public/index.php
<?php

use Phalcon\Loader; //オートローダー使うよ!って宣言
use Phalcon\Mvc\View;  //ビューを使用するために必要な宣言
use Phalcon\Mvc\Application;  //MVCの煩雑な処理はこれが行なっているらしい
use Phalcon\Di\FactoryDefault; //Phalconに付属しているコンポーネントのほとんどを登録するための宣言
use Phalcon\Mvc\Url as UrlProvider; //URLを作成するために必要な宣言

オートローダーってなんぞや?

Phalcon\Loader とは、PSR-4 に準拠したオートロードの機能を提供するためのクラスです。
これを利用することによって、Phalcon は Composer に依存しないオートロードを実装することが出来ます。

だそうです。
このサイトが分かりやすい
What about Phalcon\Loader

あとは、宣言なので、ふーんっていう感じでいいのかな?

index.php
// Define some absolute path constants to aid in locating resources
define('BASE_PATH', dirname(__DIR__)); //
define('APP_PATH', BASE_PATH . '/app');

define('A', 'B'); で、AをBと定義するという用法ですね。

dirname(_DIR_)は、そのファイルが存在するディレクトリなので、
この場合は、BASE_PATH = そのファイルが存在するディレクトリ と定義したということですね。
同様にAPP_PATHもパスを定義しています。

参考:自動的に定義される定数

// Register an autoloader
$loader = new Loader(); //オートローダーを作る

$loader->registerDirs(
    [
        APP_PATH . '/controllers/',
        APP_PATH . '/models/',
    ]
);

$loader->register(); //上で定義したオートローダーを登録

これは、オートローダーを作って、ディレクトリを登録しておきます。
ここでは、controllersとmodelsを登録します。

// Create a DI
$di = new FactoryDefault();

DIを作ります。
DIは、phlconの特徴の一つでもあるので、知っておきましょう!!
猿でも分かる! Dependency Injection: 依存性の注入

// Setup the view component
$di->set(
    'view',
    function () {
        $view = new View(); //新しいviewを作る
        $view->setViewsDir(APP_PATH . '/views/'); //パスを「/views/」に指定する
        return $view; //変数viewを返します
    }
);

Viewの部分を作っていきます。htmlとかがある場所ですね。
viewをセットして、第二引数の関数の中に実行したいことを記します。

// Setup a base URI
$di->set(
    'url',
    function () {
        $url = new UrlProvider();
        $url->setBaseUri('/');
        return $url;
    }
);

ベースとなるURIを作ります。
URLとURIは何が違うの? どちらが正しい呼び方?

urlをセットして、第二引数に実行したいことを記します。
変数urlに、新しいUrlProviderを作って、パスは現在置で良いので、「/」としているのでしょう。
変数urlを返します。

$application = new Application($di);

try {
    // Handle the request
    $response = $application->handle(); 

    $response->send();
} catch (\Exception $e) {
    echo 'Exception: ', $e->getMessage();
}

applicationの存在意義がわからない・・・そこで調べてみると、このようなことが書かれていました。難しい。

PhalconでのMVCの操作をオーケストレーションする背後にあるすべてのハードワークは、通常、Phalcon \ Mvc \ Applicationによって行われます。このコンポーネントは、必要なすべての複雑なオペレーションをバックグラウンドでカプセル化し、必要なすべてのコンポーネントをインスタンス化し、MVCパターンを必要に応じて動作させるためにプロジェクトと統合します。

applicationに一度放り込んで、複雑な処理をするということかな?

tryは例外処理を記述する場所です。
まずは、何か実行することを記します。

何かを行うときは、handleを使うそうで、この場合、responseを使いますよっていうことかな?
applicationを代入しているので、resoponseを返すということは、applicationを実行するっていうことかな。

例外が発生したら、エラーのメッセージを返すようになっていますね。

ちなみに
例外処理の記述はこう書くそうです

try {
    // 例外が発生する可能性のあるコード
} catch (Exception $e) {
    // 例外が発生した場合に行う処理
}

次に、コントローラーを見ていきます。

app/controllers/IndexController.php
<?php

use Phalcon\Mvc\Controller; //コントローラーを使うために必要なやつ

class IndexController extends Controller
{
    public function indexAction()
    {

    }
}

Controllerを継承して、IndexControllerというクラスを作ります。
indexActionは、「index」というのviewを参照するので、index.phtmlという名前にしておきます。
ちなみに、indexControllerは、indexフォルダを参照しますので、indexフォルダのindex.htmlを参照するということになります。

indexというフォルダの中に、index.phtmlを作りましょう。

index/phtmlを作る

app / views / index / index.phtml
<?php echo "<h1>Hello!</h1>";

コントローラーから、viewが参照されたので、helloを出力するプログラムを書きます。
そうすると、xamppでローカルホストに行くと、Hello!と表示されるでしょう。

サインアップフォームの設計の部分

index.phtmlを書き換える

サインアップフォームの場合は、Hello!の下にsign up here!という文字を作ってみましょう!

```app / views / index / index.phtml
<?php

echo "

Hello!

";

echo PHP_EOL; //改行

echo PHP_EOL; //改行

echo $this->tag->linkTo(
"signup",
"Sign Up Here!"
);
```

tag->linkTO でリンクを生成します。
signupに行くリンクを生成します(ブラウザには、「」Sign Up Here!)と表示される。

つまり、通常のhtmlなら、こんな感じになっているということです。

<h1>Hello!</h1>

<a href="/signup">Sign Up Here!</a>

SignupControllerを作る

app/controllers/SignupController.php
<?php

use Phalcon\Mvc\Controller;

class SignupController extends Controller
{
    public function indexAction()
    {

    }
}

SignupControllerは、signupフォルダを参照します。
Controllerを継承して、SignupControllerというクラスを作り、
indexActionでindex.phtmlを参照します。

signup用のindex.phtmlを作る

app/views/signup/index.phtml
<h2>Sign up using this form</h2>

<?php echo $this->tag->form("signup/register"); ?> //formタグを作って、signupコントローラーのregisterActionに飛ぶように設定

    <p>
        <label for="name">Name</label> //「Name」と表示されるラベルを作る
        <?php echo $this->tag->textField("name"); ?> //テキストを書くフィールドを作る
    </p>

    <p>
        <label for="email">E-Mail</label>  //「E-Mail」と表示されるラベルを作る
        <?php echo $this->tag->textField("email"); ?> //テキストを書くフィールドを作る
    </p>

    <p>
        <?php echo $this->tag->submitButton("Register"); ?> //Registerボタンを作る
    </p>

</form>

モデルを作る

まずデータベースの設定から

ターミナルで以下のコマンドを打ちます。これで、ターミナルからxamppのphpmyadminに入れます。
この後パスワードを入力してください。
(ここは、チュートリアルにはありません。)

/Applications/XAMPP/xamppfiles/bin/mysql -u root -p

データベースを作ります。ここでは、phalcon_testという名前のデータベースを作ってみました。
ターミナルで下記のコマンドを打ってください。
(ここはチュートリアルにありません。)

create database phalcon_test;

このデータベースを使うことを宣言します。

use phalcon_test;

次にテーブルを作ります。
これはチュートリアルのやつですね。
ターミナルに打ち込みます。

CREATE TABLE `users` (
    `id`    int(10)     unsigned NOT NULL AUTO_INCREMENT,
    `name`  varchar(70)          NOT NULL,
    `email` varchar(70)          NOT NULL,

    PRIMARY KEY (`id`)
);

モデルを作ります

app/models/Users.php
<?php

use Phalcon\Mvc\Model; //モデルを使います!という宣言

class Users extends Model //Modelクラスを継承して、Usersというクラスを作成(Usersテーブルを参照という意味になります)
{
    public $id; 
    public $name;
    public $email;
}

モデルの働きを確認すると、、、

モデルは、主に、対応するデータベーステーブルとの相互作用のルールを管理するために使用されます。

なるほど。
データベーステーブルの情報を書いていけばいいんですね。

ちなみに、publicを使うと、どこからでも読み取り・変更できるようになるらしい・・・。publicがいまいち分からんな。。。

データベースとの接続

チュートリアルにもある以下のコードをindex.phpに追記します。

public/index.php
use Phalcon\Db\Adapter\Pdo\Mysql as DbAdapter;

// Setup the database service
$di->set(
    'db',   //DIにdbをセット
    function () {
        return new DbAdapter(
            [
                'host'     => 'localhost', //xamppでやっているのでローカルホストを指定
                'username' => 'root', //phpmyadminにログインするときのユーザー名
                'password' => 'secret', //phpmyadminにログインするときのパスワード
                'dbname'   => 'phalcon_test',  //他のデータベース名にした人は、そのデータベース名を指定
            ]
        );
    }
);

モデルを使用したデータの保存

app/controllers/SignupController.php
<?php

use Phalcon\Mvc\Controller; //コントローラを使います!

class SignupController extends Controller //Controllerを継承して、 SignuoControllerクラスを作成(signupフォルダを参照するようになります)
{
    public function indexAction() //index.phtmlを実行
    {

    }

    public function registerAction() register //register.phtmlがあれば、それを実行するが、ないので、以下のコードを実行
    {
        $user = new Users();  //usersを作成

        // Store and check for errors
        $success = $user->save(   //saveはレコードの作成、更新ができる
            $this->request->getPost(),   //requestを$_POST[$name]と$_POST[$email]で返す
            [
                "name",
                "email",
            ]
        );

        if ($success) {  //もし$successがあれば(さっきのがうまくいったら)
            echo "Thanks for registering!"; //Thanks for registering!と表示
        } else {  //もし$successがなければ(さっきのがうまくいかなかったら)
            echo "Sorry, the following problems were generated: ";  //Sorry, the following problems were generated:と表示

            $messages = $user->getMessages(); //生成されたメッセージは、getMessages()メソッドで取得できる、それを$messagesに代入

            foreach ($messages as $message) {
                echo $message->getMessage(), "<br/>"; //データを表示
            }
        }

        $this->view->disable(); //register.phtmlがあれば、それを表示しちゃうので、viewの機能を遮断しました。
    }
}

中に全部書いてしまった笑
終わりです。