🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] # 基础教程 在本教程中,我们将引导您从头开始创建一个简单注册表单的应用程序。以下指南将向您介绍Phalcon框架的设计方面。 本教程介绍了一个简单的MVC应用程序的实现,展示了使用Phalcon可以快速轻松地完成它。本教程将帮助您入门并帮助创建可扩展的应用程序以满足许多需求。本教程中的代码也可以用作学习其他Phalcon特定概念和想法之地。 <div class="alert alert-info"> <p> <iframe width="560" height="315" src="https://www.youtube.com/embed/75W-emM4wNQ" frameborder="0" allowfullscreen></iframe> </p> </div> 如果您只是想开始使用,可以跳过此步骤并使用我们的开发者工具自动创建Phalcon项目。(如果你没有经验,如果你遇到困难,可以回到这里) 使用本指南的最佳方式是跟随并尝试获得乐趣。您可以在此处获取完整的代码。如果您对某些事情感到不知所措,请访问我们的[Discord](https://phalcon.link/discord)或我们的[论坛](https://phalcon.link/forum)。 ## 文件结构 Phalcon的一个关键特性是松散耦合,您可以构建一个Phalcon项目,其目录结构便于您的特定应用程序。这表示在与其他人合作时,一些统一性是有用的,因此本教程将使用“标准”结构,如果您过去曾与其他MVC合作过,您应该有宾至如归的感觉。 ```text . └── tutorial ├── app │   ├── controllers │   │   ├── IndexController.php │   │   └── SignupController.php │   ├── models │   │   └── Users.php │   └── views └── public ├── css ├── img ├── index.php └── js ``` >[warning] 注意:您不会看到`vendor`目录,因为所有Phalcon的核心依赖项都是通过您应该安装的Phalcon扩展加载到内存中的。如果您错过了那部分尚未安装Phalcon扩展请返回并完成安装,然后继续。 如果这是全新的,建议您安装Phalcon Devtools,因为它利用PHP的内置服务器来运行您的应用程序,而无需通过将此[.htrouter](https://github.com/phalcon/phalcon-devtools/blob/master/templates/.htrouter.php) 添加到项目的根目录来配置Web服务器。 否则,如果你想使用Nginx,请查看`Web服务器设置`章节。 Apache也可以在`Web服务器设置`使用这些附加设置。 最后,如果你的最爱是Cherokee,请查看`Web服务器设置`章节。 ## Bootstrap 您需要创建的第一个文件是启动程序文件。此文件充当应用程序的入口点和配置。在此文件中,您可以实现组件的初始化以及应用程序行为。 这个文件处理3件事: - 注册自动加载组件 - 配置服务并使用依赖注入上下文注册它们 - 解析应用程序的HTTP请求 ### 自动加载 自动加载器利用通过Phalcon运行的兼容[PSR-4](http://www.php-fig.org/psr/psr-4/)的文件加载器。应添加到自动装带器的常见事项是控制器和模型。您可以注册将在应用程序命名空间中搜索文件的目录。如果您想了解其他可以使用自动加载器的方法,请访问`类加载器`章节。 首先,让我们注册我们的应用程序的`controllers`和`models`目录。不要忘记包括`Phalcon\Loader`的加载器。 `public/index.php` ```php <?php use Phalcon\Loader; // 定义一些绝对路径常量以帮助定位资源 define('BASE_PATH', dirname(__DIR__)); define('APP_PATH', BASE_PATH . '/app'); // ... $loader = new Loader(); $loader->registerDirs( [ APP_PATH . '/controllers/', APP_PATH . '/models/', ] ); $loader->register(); ``` ### 依赖管理 由于Phalcon松耦合,因此服务在框架依赖管理中注册,因此可以将它们自动注入包含在[IoC](https://en.wikipedia.org/wiki/Inversion_of_control)容器中的组件和服务。通常你会遇到DI这个词代表依赖注入。依赖注入和控制反转(IoC)可能听起来像一个复杂的功能,但在Phalcon中它们的使用非常简单实用。Phalcon的IoC容器包含以下概念: - 服务容器:一个“包”,我们在全局存储我们的应用程序需要运行的服务。 - 服务或组件:将注入组件的数据处理对象 每次框架需要组件或服务时,它都会使用商定的名称来询问容器。不要忘记在设置服务容器时包含`Phalcon\Di`. >[warning] 如果您对详细信息仍感兴趣,请参阅[Martin Fowler](https://martinfowler.com/articles/injection.html)的这篇文章。我们在`依赖注入与服务定位`章节也涵盖了很多用例。 ### 默认工厂 `Phalcon\Di\FactoryDefault`是`Phalcon\Di`的变种。为了简化操作,它将自动注册Phalcon附带的大多数组件。我们建议您手动注册您的服务,但这已经包含在内,以帮助降低习惯依赖管理时的入门门槛。之后,一旦您对这个概念感到满意,您就可以随时指定。 服务可以通过多种方式注册,但是对于我们的教程,我们将使用[匿名函数](http://php.net/manual/en/functions.anonymous.php): `public/index.php` ```php <?php use Phalcon\Di\FactoryDefault; // ... // Create a DI $di = new FactoryDefault(); ``` 在下一部分中,我们注册“view”服务,指示框架将查找视图文件的目录。由于视图与类不对应,因此无法使用自动加载器载入。 `public/index.php` ```php <?php use Phalcon\Mvc\View; // ... // Setup the view component $di->set( 'view', function () { $view = new View(); $view->setViewsDir(APP_PATH . '/views/'); return $view; } ); ``` 接下来,我们注册一个基URI,以便Phalcon生成的所有URI都与应用程序的基本路径“/”匹配。当我们使用`Phalcon\Tag` 类生成超链接时,这将在本教程的后面变得很重要。 `public/index.php` ```php <?php use Phalcon\Mvc\Url as UrlProvider; // ... // Setup a base URI $di->set( 'url', function () { $url = new UrlProvider(); $url->setBaseUri('/'); return $url; } ); ``` ### 处理应用请求 在这个文件的最后一部分,我们找到了`Phalcon\Mvc\Application`。其目的是初始化请求环境,路由传入的请求,然后分派任何发现的操作;它聚合任何响应并在过程完成时返回它们。 `public/index.php` ```php <?php use Phalcon\Mvc\Application; // ... $application = new Application($di); $response = $application->handle(); $response->send(); ``` ### 合并 `tutorial/public/index.php`文件应如下所示: `public/index.php` ```php <?php use Phalcon\Loader; use Phalcon\Mvc\View; use Phalcon\Mvc\Application; use Phalcon\Di\FactoryDefault; use Phalcon\Mvc\Url as UrlProvider; // 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(); } ``` 如您所见,bootstrap文件非常短,我们不需要包含任何其他文件。恭喜您在不到30行代码中创建灵活的MVC应用程序。 ## 创建控制器 默认情况下,Phalcon将查找名为`IndexController`的控制器。它是在请求中未添加任何控制器或操作的起点(例如,`http://localhost:8000/`)。IndexController及其IndexAction应类似于以下示例: `app/controllers/IndexController.php` ```php <?php use Phalcon\Mvc\Controller; class IndexController extends Controller { public function indexAction() { echo '<h1>Hello!</h1>'; } } ``` 控制器类必须具有后缀`Controller`,控制器操作必须具有后缀`Action`。如果您从浏览器访问该应用程序,您应该看到如下内容: ![](https://docs.phalconphp.com/images/content/tutorial-basic-1.png) 恭喜你,你正在使用Phalcon! ## 将输出发送到视图 有时需要从控制器向屏幕发送输出,但不可取,因为MVC社区中的大多数纯粹主义者都会证明。必须将所有内容传递给负责在屏幕上输出数据的视图。Phalcon将查找与名称为最后执行的控制器的目录中最后执行的操作同名的视图。在我们的例子中(`app/views/index/index.phtml`): `app/views/index/index.phtml` ```php <?php echo "<h1>Hello!</h1>"; ``` 我们的控制器(`app/controllers/IndexController.php`)现在有一个空的动作定义: `app/controllers/IndexController.php` ```php <?php use Phalcon\Mvc\Controller; class IndexController extends Controller { public function indexAction() { } } ``` 浏览器输出应保持不变。当动作执行结束时,将自动创建`Phalcon\Mvc\View`静态组件。在`使用视图`章节详细了解视图使用情况。 ## 设计注册表单 现在我们将更改`index.phtml`视图文件,以添加指向名为“signup”的新控制器的链接。目标是允许用户在我们的应用程序中注册。 `app/views/index/index.phtml` ```php <?php echo "<h1>Hello!</h1>"; echo PHP_EOL; echo PHP_EOL; echo $this->tag->linkTo( 'signup', 'Sign Up Here!' ); ``` 生成的HTML代码显示链接到新控制器的锚(`<a>`)HTML标记: `app/views/index/index.phtml` (渲染) ```html <h1>Hello!</h1> <a href="/signup">Sign Up Here!</a> ``` 要生成标记,我们使用`Phalcon\Tag`类。这是一个实用程序类,它允许我们构建具有框架约定的HTML标记。由于此类也是在DI中注册的服务,因此我们使用`$this->tag`来访问它。 A more detailed article regarding HTML generation [can be found here](/[[language]]/[[version]]/tag). 有关HTML生成的更详细的文章可以在`视图助手(标签)`章节找到。 ![](https://docs.phalconphp.com/images/content/tutorial-basic-2.png) 这是注册控制器(`app/controllers/SignupController.php`): `app/controllers/SignupController.php` ```php <?php use Phalcon\Mvc\Controller; class SignupController extends Controller { public function indexAction() { } } ``` 空索引操作使用表单定义(`app/views/signup/index.phtml`)为视图提供干净的传递: `app/views/signup/index.phtml` ```html <h2>Sign up using this form</h2> <?php echo $this->tag->form("signup/register"); ?> <p> <label for="name">Name</label> <?php echo $this->tag->textField("name"); ?> </p> <p> <label for="email">E-Mail</label> <?php echo $this->tag->textField("email"); ?> </p> <p> <?php echo $this->tag->submitButton("Register"); ?> </p> </form> ``` 在浏览器中查看表单将显示如下内容: ![](https://docs.phalconphp.com/images/content/tutorial-basic-3.png) `Phalcon\Tag`还提供了构建表单元素的有用方法。 `Phalcon\Tag::form()`方法仅接收一个参数,例如,应用程序中控制器/操作的相对URI。 通过单击“Send”按钮,您将注意到框架中抛出的异常,表明我们在控制器注册中缺少`register`操作。我们的`public/index.php`文件抛出此异常: Exception: Action "register" was not found on handler "signup" 实现该方法将除去异常: `app/controllers/SignupController.php` ```php <?php use Phalcon\Mvc\Controller; class SignupController extends Controller { public function indexAction() { } public function registerAction() { } } ``` 如果再次单击“Send”按钮,您将看到一个空白页面。用户提供的名称和电子邮件输入应存储在数据库中。根据MVC指南,数据库交互必须通过模型完成,以确保干净的面向对象的代码。 ## 创建模型 Phalcon为PHP提供了第一个完全用C语言编写的ORM。它不是增加开发的复杂性,而是简化了它。 在创建我们的第一个模型之前,我们需要在Phalcon之外创建一个数据库表来映射它。可以像这样创建一个存储注册用户的简单表: `create_users_table.sql` ```sql 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`目录(`app/models/Users.php`)中。该模型映射到“users”表: `app/models/Users.php` ```php <?php use Phalcon\Mvc\Model; class Users extends Model { public $id; public $name; public $email; } ``` ## 设置数据库连接 为了使用数据库连接并随后通过我们的模型访问数据,我们需要在我们的引导过程中指定它。数据库连接只是我们的应用程序可以用于多个组件的另一个服务: `public/index.php` ```php <?php use Phalcon\Db\Adapter\Pdo\Mysql as DbAdapter; // Setup the database service $di->set( 'db', function () { return new DbAdapter( [ 'host' => '127.0.0.1', 'username' => 'root', 'password' => 'secret', 'dbname' => 'tutorial1', ] ); } ); ``` 使用正确的数据库参数,我们的模型可以工作并与应用程序的其余部分进行交互。 ## 使用模型存储数据 `app/controllers/SignupController.php` ```php <?php use Phalcon\Mvc\Controller; class SignupController extends Controller { public function indexAction() { } public function registerAction() { $user = new Users(); // Store and check for errors $success = $user->save( $this->request->getPost(), [ "name", "email", ] ); if ($success) { echo "Thanks for registering!"; } else { echo "Sorry, the following problems were generated: "; $messages = $user->getMessages(); foreach ($messages as $message) { echo $message->getMessage(), "<br/>"; } } $this->view->disable(); } } ``` 在`registerAction`的开头,我们从Users类创建一个空的用户对象,该类管理用户的记录。该类的公共属性映射到数据库中`users`表的字段。在新记录中设置相关值并调用`save()`会将数据存储在该记录的数据库中。`save()`方法返回一个布尔值,指示数据的存储是否成功。 ORM自动转义阻止SQL注入的输入,因此我们只需要将请求传递给`save()`方法。 在定义为非null(必需)的字段上自动进行附加验证。如果我们没有在注册表单中输入任何必填字段,我们的屏幕将如下所示: ![](https://docs.phalconphp.com/images/content/tutorial-basic-4.png) ## Conclusion 如您所见,使用Phalcon开始构建应用程序很容易。Phalcon从扩展中运行的事实大大减少了项目的占地面积,并使其具有相当大的性能提升。 如果您准备了解更多信息,请查看`教程:创建一个简单的REST API`章节。