Konstrukt是一个用PHP开发的小型REST框架,它不是提供盒装解决所有问题的框架。它的重点是控制层,并试图以鼓励开发商直接处理HTTP协议而不是抽象它拿走。 Konstrukt采用分层控制模式,从而提供了更大程度的灵活性,较受欢迎的路由前端控制器框架。
本教程的目的是引导您与Konstrukt的编写Web应用程序的基本知识。
什么是组件
Konstrukt的一个应用程序包含的对象调用的组件。这些是基本的构建模块。一个组件结合成一个单一的逻辑实体的连带责任。最明显的方面是它有能力成为HTML的一个组成部分。
一个适当的组件不直接沟通的环境。而不是调用各种全球性功能,其所有的输入,从它的上下文。上下文可以是另一个元件,或者它可以是一个HTTP请求,所以组件是分层的。这个阶层是构建在运行时,根据传入的请求路径。我们会去更深入的后面,但通常在http://example.org/foo/bar
URL,例如,将涉及三个组成部分,一个根组件,处理富
和处理吧
。
创建一个新项目
在本教程中,我们将创建一个非常简单的应用程序。Konstrukt的不严格执行某个特定的目录布局,但提供了一个起点,你可以把文件夹的副本例子/ starterpack_light的
Konstrukt的分布的。假设你的Web根目录是/ var / www下面
,该目录拷贝到的例子/ starterpack_light
/无功/ www / foo的
为我们的应用程序“foo”的。在实际应用中,你可能需要安装其自己的虚拟主机上的应用程序,但是这是一个快速的方式开始,这是微不足道的移动应用程序。下载最新版本的Konstrukt的http://github.com/troelskn/konstrukt/downloads。然后复制starterpack_light
:
cp -R examples/starterpack_light /var/www/foo
starterpack_light
是一个基本的设置,它包含一个简单的目录结构,和其他的东西,你需要开始一个Web应用程序。还有一个更完整的安装在starterpack_default
新的应用程序,这是建议的原因,我们在本教程中使用最小化安装,是保持较低的外部依赖关系。
starterpack包含几个文件夹。现在,我们只关心我们自己,他们两个人,WWW
这应该是您的网站和库
的Web根,它应该包含您的应用程序的类。一旦你设置了,不常用的WWW
文件夹。
如果您使用的是UNIX系统,你可能会访问到WEB服务器写入的文件夹日志
,因为该应用程序配置为写入日志文件放在此处的各种信息。你可以简单地运行下面的命令:
chmod 777 /var/www/foo/log
现在你可以打开你的浏览器,和去http://localhost/foo/www
和验证,一切都是为了。下面的消息应该满足你如果一切运行正常:
根
此页有意留为空白
这是根组件renderHtml()
函数的输出。如果你打开文件/var/www/foo/lib/components/root.php部分的
,你会看到它呈现的输出使用一个基本的模板。如果你想用不同的模板引擎(也许没有),你可以自由改变。重要的是,renderHtml()
方法返回一个字符串-它是如何产生的,是不关心Konstrukt的。
模型层
所以,现在我们有安装运行,让我们得到了应用。为了简单起见,我们只创建一个应用程序,可以从数据库中显示联系人。我知道这是枯燥的,但我们必须从某个地方开始。
Konstrukt的明确避免了模型层组件,把它作为开放式的尽可能。在本教程中,我们将只使用一个非常简单的模型组件。将以下内容保存为/var/www/foo/lib/contactsgateway.php
:
<?php
class ContactsGateway {
protected $db;
function __construct(PDO $db) {
$this->db = $db;
}
function save($contact) {
$statement = $this->db->prepare(
"update contacts set
first_name = :first_name,
last_name = :last_name,
email = :email
where short_name = :short_name");
$statement->execute(
array(
':first_name' => $contact->first_name(),
':last_name' => $contact->last_name(),
':email' => $contact->email(),
':short_name' => $contact->short_name()));
}
function fetchByName($short_name) {
$statement = $this->db->prepare("select * from contacts where short_name = :short_name");
$statement->execute(array(':short_name' => $short_name));
return new Contact($statement->fetch(PDO::FETCH_ASSOC));
}
function all() {
$statement = $this->db->prepare("select * from contacts");
$statement->execute();
$result = array();
foreach ($statement as $row) {
$result[] = new Contact($row);
}
return $result;
}
}
这是 /var/www/foo/lib/contact.php
:
<?php
class Contact {
protected $row;
function __construct($row) {
$this->row = $row;
}
function full_name() {
return $this->first_name() . " " . $this->last_name();
}
function short_name() {
return $this->row['short_name'];
}
function first_name() {
return $this->row['first_name'];
}
function last_name() {
return $this->row['last_name'];
}
function email() {
return $this->row['email'];
}
}
使用我们的模型组件,我们需要一个数据库。由于SQLite是与大多数PHP安装的标准,这是最简单的数据库安装,我会假设,但这个简单的例子同样出色的工作与MySQL或任何其它SQL数据库的问题。
由于SQLite的数据库存储在一个文件中,我们需要它的位置。我们将创建一个文件夹下你的项目:
mkdir var chmod 777 var
注:如果您使用的是Windows,你可以跳过属性
的一部分。
登录到我们的数据库SQLite和创建在/ var / www下面/ foo的/ VAR / database.sqlite的的
。在命令行输入:
sqlite3 var/database.sqlite
创建数据库下面的SQL语句:
CREATE TABLE contacts (
id SERIAL,
short_name VARCHAR(100) NOT NULL,
first_name VARCHAR(100) NOT NULL,
last_name VARCHAR(100) NOT NULL,
email VARCHAR(100) NOT NULL,
UNIQUE (short_name)
);
INSERT INTO contacts (short_name, first_name, last_name, email)
VALUES (
"jabba",
"Jabba",
"the Hutt",
"jabba@tatooine.com");
INSERT INTO contacts (short_name, first_name, last_name, email)
VALUES (
"jar-jar",
"Jar Jar",
"Binks",
"jarjar@naboo.com");
同样,由于Web服务器需要访问数据库,我们将有松懈的文件的权限:
chmod 666 var/database.sqlite
相反,普遍接受的做法,我们将创建一个全球性的数据库的链接,我们可以在整个应用程序中使用。这显然不是你应该做的,但在实际应用中继续专注于控制层现在,我们将做到这一点没有少。然后,我们可以在以后更改使用依赖注入的技术,这是推荐的方法。打开config /中global.inc.php
,并添加以下几行:
$db = new PDO("sqlite:" . dirname(dirname(__FILE__)) . "/var/database.sqlite");
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$contacts = new ContactsGateway($db);
注意:您需要在您的系统上安装SQLite和PDO。theese是两个单独的扩展。如果你得到错误消息“PDOException中:无法找到驱动程序”,它意味着你有PDO,但不PDO_SQLITE的。在基于Debian的系统,要安装的软件包php5-sqlite的的
。
注意:SQLite版本2和3是不能直接兼容。如果你得到一个错误信息,说“文件是加密的,或不是一个数据库”,你可能创建的数据库第2版,而PHP扩展版本3。从命令行使用的工具,而不是sqlite的
sqlite3的
。
添加一个组件,最后
现在,我们的先决条件是在地方,让我们的组件。您可能还记得,我们的应用程序目前只能处理一个请求为/ foo / WWW
(根)。因为我们希望它显示接触,让我们添加一个组件。将以下内容保存到/ var /网络/富/ lib目录/组件/联系我们/ list.php的
:
<?php
class components_contacts_List extends k_Component {
function renderHtml() {
global $contacts;
$this->document->setTitle("Contacts");
$t = new k_Template("templates/contacts-list.tpl.php");
return $t->render(
$this,
array(
'contacts' => $contacts->all()));
}
}
这是一个相当简单的组成部分。它实现了的功能renderHtml()
,这将被称为一个基本的GET请求,如果客户端支持的格式(做所有的浏览器)。您也可以选择执行的get()
调用,这将是任何形式的GET请求,但通常你不需要这个。也有处理程序(POST和其他更奇特的HTTP方法),它遵循相似的命名方案。
正如你可以看到,我们指的全局变量$接触
,这是我们在global.inc.php
创建。接下来我们创建一个模板实例,并分配给所有接触到它,在渲染为一个字符串并返回结果。一个k_Template
是一个非常简单的包装,包括
-它只是返回一个字符串的输出。
很显然,我们还需要一个模板,因此将以下内容保存到/ var /网络/富/模板/联系人- list.tpl.php的
:
<h2>Contacts</h2>
<ul>
<?php foreach ($contacts as $contact): ?>
<li><a href="<?php e(url($contact->short_name())); ?>"><?php e($contact->full_name()); ?></a></li>
<?php endforeach; ?>
</ul>
现在,我们的组件是能够从数据库中渲染联系。在此之前,虽然可能发生,我们需要将URL映射到新的组件。我们希望有一个网址为/ foo / WWW /联系人
等,因此,我们将打开上一个组件-根。添加以下几行到/ var /网络/富/ lib目录/组件/ root.php
:
<?php
class components_Root extends k_Component {
function map($name) {
if ($name == 'contacts') {
return 'components_contacts_List';
}
}
...
这告诉的根组件名称转发接触
到我们的新组件。您现在应该能够,导航到http://localhost/foo/www/contacts
看到的联系人列表。,这是一个很短的列表。
注:如果这不起作用,你可能已经Apache的配置错误。您需要启用mod_rewrite模块
,并允许本地配置的。htaccess
文件。你可以寻找帮助,这对我们的友好论坛。
上下文转发
现在,我们可以得到一个可用的接触,但是我们仍然需要一个网页,可以充分显示他们在。正如你可能已经注意到了,我用的是函数内的旧模板的网址
。这仅仅是速记的组件URL
的方法。k_Template
需要照顾的代表团。的URL
方法生成一个URL,它指向一个地方,相对当前的组件。因此内的components_contacts_List
,你将得到的URL像http://localhost/foo/www/contacts/jabba
。现在,点击theese链接不会给我们任何可用的结果。所以,让我们确保它。
首先,我们修改的components_contacts_List的
组成部分,以允许转发:
<?php
class components_contacts_List extends k_Component {
function map($name) {
return 'components_contacts_Entity';
}
...
请注意,如何components_contact_Entity
的使用,无论什么名字。现在,我们需要创建新转介的组件。保存为/ var /网络/富/ lib目录/组件/联系人/ entity.php的
:
<?php
class components_contacts_Entity extends k_Component {
function renderHtml() {
global $contacts;
$contact = $contacts->fetchByName($this->name());
if (!$contact) {
throw new k_PageNotFound();
}
$this->document->setTitle($contact->full_name());
$t = new k_Template("templates/contacts-entity.tpl.php");
return $t->render($this, array('contact' => $contact));
}
}
有两个新的东西,要注意有关此组件。首先,我们使用的名称()
方法来访问的URL路径名。这是使用的上下文的名称,以确定此组件。我们使用它来 从数据库中选择相关的联系。
接下来的事情是,我们抛出一个异常,如果没有发现接触。Konstrukt的定义了一些特定的例外情况外,在HTTP协议中,映射到特定的含义。例如,k_PageNotFound
会发出一个404页面未找到。掰经常渲染管线了异常的使用使得有可能封装组件的影响。
要完成的图片,我们需要一个模板来匹配我们的组件。保存为/ var /网络/富/模板/联系人- entity.tpl.php的
:
<h2><?php e($contact->short_name()); ?></h2>
<dl>
<dt>First Name</dt>
<dd><?php e($contact->first_name()); ?></dd>
<dt>Last Name</dt>
<dd><?php e($contact->last_name()); ?></dd>
<dt>Email</dt>
<dd><?php e($contact->email()); ?></dd>
</dl>
有了这个,我们现在可以显示我们的联系方式。继续点击这些链接从上市。
总结了我们今天的会议。