Typecho Framework是SegmentFault所用的框架,本文将介绍如何用这个框架写一个Hello World程序。如果你不了解Typecho Framework,请先看这篇简介。
输出Hello World!
首先我们创建Hello World程序的目录:
mkdir ~/hellow-world
Action从Service获取所需数据后,传递result给Server的响应对象。
Hello World!
不需要获取数据,所以我们直接让Action返回一个result即可。
在hello-world目录下建立app/Action/
目录,并在其中创建Hello.php
文件:
namespace Hello\Action;
首先我们定义一个命名空间,我们的程序使用Hello为命名空间。
这是一个Action,所以我们需要继承Action的类,翻一下框架的源代码,找到这样一个文件Mvc/Action/AbstractAction.php,那我们就继承AbstractAction
这个类好了:
use TE\Mvc\Action\AbstractAction;
/**
* Hello
*
* @use AbstractAction
*/
class Hello extends AbstractAction
{
// 待填充
}
我们看到Mvc/Action/AbstractAction.php里有这样一行代码:
abstract public function execute();
这就告诉我们,需要在自己的类中实现这个execute
方法。我们实现一下这个方法,返回一个result数组。这时我们参考下Typecho Framework的示例代码,发现它是这么写的:
public function execute()
{
// 只要你把Action的属性设置为public状态,它就会被注入到模板中,你可以直接在模板中使用它们
$this->word = 'Hello World';
$this->peoples = new People($this->peopleService->listNewest(1, 20));
$this->master = new People($this->peopleService->getByName('joyqi')); // 不论你取出一行还是多行数据,都可以塞到Data对象中进行处理
return array('template', 'index.php');
}
嗯,看这行代码的意思,应该是指定返回的result使用模板(index.php
是模板文件的名称)。那么我们不用模板,直接返回一个字符串应该怎么写呢?
继续翻源代码,发现Mvc/View
目录下是这样的结构:
- AbstractView.php
- Back.php
- Blank.php
- Content.php
- Error.php
- Json.php
- Jsonp.php
- NotFound.php
- Redirect.php
- Template.php
嗯,我们返回Hello World!
,不用模板,也不用什么Json,那么应该是Content
了。点进去一看,果然是这个:
/**
* 渲染一个字符串
*
好了,知道了result数组要用content
后,我们来完成这个方法的定义:
class Hello extends AbstractAction
{
public function execute()
{
return array('content', 'Hello World!');
}
}
路由
好了,Action部分已经搞定,接下来我们绑定一下路由。参考示例代码,我们新建一个config
目录,然后创建routes.php
,内容如下:
return [
'/Hello' => 'Hello\Action\Hello',
];
路由设置很简单,就是返回一个数组,将路径绑定到相应的类。
入口程序
这样基本上就完成了。还剩下一个入口程序了。示例代码的README中提到:
直接在浏览器里输入http://app-root/portal/index.php即可, 其中
app-root
是你的程序目录
所以说portal/index.php
就是入口程序。这里我们直接在hello-world目录下面创立一个index.php
文件作为入口,参考示例程序的写法,我们的文件内容如下:
const ROOT = __DIR__;
require_once ROOT . '/typecho/Helper/Autoloader.php';
首先我们加载Autoloader,通过这个Autoloader来初始化程序:
use TE\Helper\Autoloader;
use TE\Mvc\Base;
use TE\Mvc\Server\Http\Server;
use TE\Mvc\Router\Simple;
Autoloader::registerNamespace(ROOT . '/typecho', 'TE');
Autoloader::registerNamespace(ROOT . '/app', 'Hello');
注册命名空间,第一个参数是路径,第二个参数是命名空间的名称。
我们把框架放在typecho
目录下。如果你还没有下载框架代码,可以克隆一下仓库:
cd ~/hello-world
git clone https://github.com/typecho/framework typecho
new Server(new Simple(require(ROOT . '/config/routes.php')));
启动服务,指定配置文件的路径。
然后在hello-world目录下运行:
php -S 127.0.0.1:8000/Hello
访问 http://127.0.0.1:8000,发现有问题,说是Server
需要两个参数,现在只有一个,缺少了一个InterceptorManager
。
缺的是拦截器,所以我们就把上面的代码改一下:
new Server(new Simple(require(ROOT . '/config/routes.php')),
new InterceptorManager(require(ROOT . '/config/interceptors.php')));
然后config/interceptors.php
里返回一个空数组(因为我们现在不需要用到拦截器):
return array();
大功告成!访问 http://127.0.0.1:8000/Hello 就能看到输出的 Hello world!
模板
上面是直接输出字符串,接下来我们使用模板输出.
先在路由里增加一条:
return [
'/Hello' => 'Hello\Action\Hello',
'/Hi' => 'Hello\Action\Hi'
];
我们打算访问/Hi
通过模板输出。
然后是实现Hi
类,创建app/Action/Hi.php
,内容如下:
namespace Hello\Action;
use TE\Mvc\Action\AbstractAction;
/**
* Hi
*
* @use AbstractAction
*/
class Hi extends AbstractAction
{
public function execute()
{
$this->msg = 'Hi!';
return array('template', 'hi.php');
}
}
我们定义了$this->msg
,在模板中可以直接使用这个变量。
最后是定义hi.php
模板。我们创建一个template
目录:
mkdir ~/hello-world/template
然后创建一个hi.php
模板文件,直接在HTML中嵌入PHP代码:
<h1><?php echo ($msg . ' ' . $name); ?></h1>
注意,我们并没有指定模板文件的位置!如果你把模板文件放在别的目录下,会报错Template file not found
。Typecho Framework会自动在template
目录下找模板文件,“约定大于配置”。
撰文 SegmentFault
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。