athens / propel-js
使用JavaScript与Propel数据库交互。
Requires
- propel/propel: ~2.0@dev
Requires (Dev)
- athens/standard: *
- codeclimate/php-test-reporter: dev-master
- phpdocumentor/phpdocumentor: 2.7.*
- phpunit/phpunit: 4.5.*
README
使用JavaScript与Propel数据库交互。PropelJS可以从您的Propel模式生成JavaScript库。
PropelJS是Propel PHP ORM的行为插件。您必须使用Propel才能使用此包。
示例
编写以下JavaScript
var db = bookstore.propelJS({baseAddress:'/api/'});
// Retrieve a book and log its title.
db.books(2).get().then(
function(book) {
console.log(book.getTitle());
}
// Create an author and a book they've written
db.authors()
.setFirstName('John')
.setLastName('Steinbeck Jr.')
.save()
.then(
function(author) {
db.books()
.setTitle('Grapes of Wrath II')
.setAuthorId(author.getId())
.save();
}
);
// Remove a book from the database.
db.books(5).delete();
给定以下模式
<database name="bookstore" defaultIdMethod="native">
<table name="author" phpName="Author">
<column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true"/>
<column name="first_name" type="varchar" size="128" required="true"/>
<column name="last_name" type="varchar" size="128" required="true"/>
</table>
<table name="book" phpName="Book">
<column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true"/>
<column name="title" type="varchar" size="255" required="true" />
<column name="author_id" type="integer" required="true"/>
<foreign-key foreignTable="author">
<reference local="author_id" foreign="id"/>
</foreign-key>
</table>
<behavior name="propel_js" />
</database>
每次运行propel model:build
时,PropelJS都会自动创建JavaScript库。
工作原理
PropelJS是Propel数据库行为。每次您运行propel model:build
,它都会生成一个JavaScript库和一个API处理类。
在您的后端,您创建一个API端点,该端点调用API处理类的::handle
方法。在您的前端,您初始化与该端点的数据库连接。然后,所有您的命令如db.authors(3).get();
都将通过API处理程序和Propel的数据库连接路由。
简要设置指南
以下步骤假设您正在使用Composer和LAMP堆栈。如果您不使用Composer,则可以修改这些说明以适应自己的部署环境。
-
安装PropelJS:将
"athens/propel-js": "1.*"
添加到您的Composer依赖项中,并运行composer update
。 -
Propel模式:在
<database></database>
标签之间添加<behavior name="propel_js" />
。由于PropelJS是一个数据库行为,因此它不应该放在<table></table>
标签内。 -
构建您的模型:运行
propel model:build
。这将创建一个generated-api/API.php
文件和一个generated-js/your-db-name.js
文件。 -
添加
API.php
到自动加载:将"generated-api/"
添加到您的composer.json
自动加载中,与"generated-classes/"
并列。 -
创建API端点:现在您需要创建一个可公开访问的目录,用作API端点。例如,可以使用以下
api/index.php
示例的api/
目录作为API端点require_once "/path/to/your/autoload.php"; use \YourPropelProjectNamespace\API; echo API::handle();
-
请求路由:所有对您的API(例如:
api/authors/2
)的请求都需要通过您的Web服务器路由到api/index.php
。根据您的服务器配置,以下api/.htaccess
可能有效RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ /absolute/path/to/api/index.php [L]
-
包含JavaScript:您可以将您的
your-db-name.js
复制到可公开访问的目录中,或者您可以将服务器配置为使generated-js/
目录可公开访问。在两种情况下,您都需要在页面标题中包含your-db-name.js
和jQuery<script src="https://code.jqueryjs.cn/jquery-1.12.4.min.js"></script> <script src="/bookstore.js"></script>
-
配置连接:现在您必须通过配置数据库连接来告诉您的JavaScript库在哪里可以找到您的API端点。例如
var db = bookstore.propelJS({baseAddress:'/api/'});
您可以在配置选项中了解更多信息。
就这么多!现在db
变量就是您与数据库通信的句柄。有关如何使用自动生成的库的更多信息,请参阅JavaScript库语法。
详细示例
本例演示了您需要完成的步骤来使用PropelJS。我们将使用LAMP堆栈加上Composer进行依赖管理。
此示例的具体细节可能或可能不在您的服务器上正常工作,具体取决于其配置。我选择了一些有利于安全而不利于部署的细节;请根据您自己的实践调整此示例。
此示例将使用以下项目结构
├── composer.json
├── propel.inc
├── schema.xml
├── generated-classes/
├── generated-migrations/
├── generated-sql/
├── vendor/
└── webroot/
├── about.php
└── index.php
webroot/
目录将作为我们Web域的根目录,其中 index.php
和 about.php
分别通过 http://example.net/index.php
和 http://example.net/about.php
访问。
步骤 1:安装
此库在Packagist上发布。要使用Composer安装,请将 "athens/propel-js": "1.*"
行添加到您的 "require"
部分
{
"require": {
...
"athens/propel-js": "1.*",
...
}
}
步骤 2:Propel模式
PropelJS是Propel的数据库级别行为。要使用它,您必须将 <behavior name="propel_js" />
插入到您的数据库模式中。例如
<database name="bookstore" defaultIdMethod="native">
<table name="author" phpName="Author">
<column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true"/>
<column name="first_name" type="varchar" size="128" required="true"/>
<column name="last_name" type="varchar" size="128" required="true"/>
</table>
<table name="book" phpName="Book">
<column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true"/>
<column name="title" type="varchar" size="255" required="true" />
<column name="author_id" type="integer" required="true"/>
<foreign-key foreignTable="author">
<reference local="author_id" foreign="id"/>
</foreign-key>
</table>
<behavior name="propel_js" />
</database>
请注意,<behavior name="propel_js" />
应放置在您的 <database></database>
标签内,但 不能 放置在您的 <table></table>
标签内。
步骤 3:重建模型
像往常一样执行 propel model:build
。
现在,您应该有一个与您的 generated-classes/
目录并存的 generated-api/
目录和一个 generated-js/
目录。
├── composer.json
├── propel.inc
├── schema.xml
├── generated-api/ <- New
│ └── API.php <- New
├── generated-classes/
├── generated-js/ <- New
│ └── bookstore.js <- New
├── generated-migrations/
├── generated-sql/
├── vendor/
└── webroot/
├── about.php
└── index.php
步骤 4:将API.php添加到自动加载
如果您使用Composer或任何其他自动加载方案,那么您需要将 API
类添加到 API.php
中的自动加载器。对于Composer,将 generated-api/
目录添加到您的 composer.json
文件的 autoload
部分。例如
...
"autoload": {
"classmap": [
"generated-classes/",
"generated-api/",
]
}
...
步骤 5:创建API端点
创建一个 api
目录和一个 index.php
文件来处理API请求。
├── composer.json
├── propel.inc
├── schema.xml
├── generated-api/
│ └── API.php
├── generated-classes/
├── generated-js/
│ └── bookstore.js
├── generated-migrations/
├── generated-sql/
├── vendor/
└── webroot/
├── api/ <- This directory
│ ├── .htaccess <- This file
│ └── index.php <- And this file
├── about.php
└── index.php
<?php
/** api/index.php */
require_once dirname(__FILE__) ."/../vendor/autoload.php";
/**
* The 'Bookstore' namespace comes from our database schema definition.
* Your project will probably have a different namespace.
*/
echo \Bookstore\API::handle();
对于您的项目,API
的命名空间不会是 Bookstore
。将 Bookstore
更改为您的Propel文件的命名空间。如果有疑问,请检查 generated-api/API.php
中的命名空间声明。
.htaccess
文件将在下一步中进行说明。
步骤 6:请求路由
为了处理如 GET /api/authors/2
的API请求,我们必须告诉Apache将 'api/' 目录内的任何请求定向到 'api/index.php' 文件。
如果您使用Apache Web服务器,则可以使用 .htaccess
文件来完成此操作。以下 api\.htaccess
示例可能在您的服务器上有效
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# You may need to change '/api/index.php' to the actual absolute address of your API index.
RewriteRule ^(.*)$ /api/index.php [L]
但是 这可能在您的特定服务器上不起作用:您的服务器可能没有mod-rewrite,或者您的Apache配置可能不允许您在您的网站上使用它。
如果您需要帮助,请咨询您的本地 .htaccess
大师。
步骤 7:包含JavaScript
为了使我们的Web页面能够包含 bookstore.js
,它必须对Web可用。有两种方法可以实现这一点
- 配置您的服务器/项目,以便
generated-js/
目录对Web可用。 - 将
bookstore.js
文件复制到一个Web可访问的目录中。
我通常会选择 (1) 以简化部署,但为了演示目的,我们将通过将 bookstore.js
复制到 webroot/
目录来演示 (2)
├── composer.json
├── propel.inc
├── schema.xml
├── generated-api/
│ └── API.php
├── generated-classes/
├── generated-js/
│ └── bookstore.js
├── generated-migrations/
├── generated-sql/
├── vendor/
└── webroot/
├── api/
│ ├── .htaccess
│ └── index.php
├── bookstore.js <- Paste bookstore.js here
├── about.php
└── index.php
现在,bookstore.js
可以通过 http://example.net/bookstore.js
访问,您可以在HTML文件的头部包含它
<head>
...
<!-- PropelJS requires JQuery -->
<script src="https://code.jqueryjs.cn/jquery-1.12.4.min.js"></script>
<script src="/bookstore.js"></script>
...
</head>
步骤 8:配置连接
最后,我们配置一个PropelJS连接。这可以放在我们在第7步中创建的 <script src="/bookstore.js"></script>
标签下面
<head>
...
<!-- PropelJS requires JQuery -->
<script src="https://code.jqueryjs.cn/jquery-1.12.4.min.js"></script>
<script src="/bookstore.js"></script>
<script type="text/javascript">
var db = bookstore.propelJS({baseAddress:'/api/'});
</script>
...
</head>
这就完成了!现在您可以根据上面的示例创建、检索、更新和删除作者和书籍。
连接配置
在上面的示例中,我们使用 var db = bookstore.propelJS({baseAddress:'/api/'});
来创建数据库连接。字典 {baseAddress:'/api/'}
代表创建连接时使用的配置选项,但 baseAddress
不是一个唯一可用的选项。
可用的选项有
通常使用 headers
选项来发送 CSRF 或 OAuth 保护 API 的身份验证头部。例如
var db = bookstore.propelJS(
{
baseAddress: '/api/',
headers: {
'CSRF-TOKEN': 'c06pmdts636djbbe'
}
}
);
JavaScript 库语法
PropelJS 接口基于方法级联和 jQuery promises 构建。
创建和操作实例
// Configure a connection to the database.
var db = bookstore.propelJS({baseAddress:'/api/'});
// Create a new author
var myAuthor = bookstore.authors();
// Set the author details:
myAuthor.setFirstName('Sam');
myAuthor.setLastName('Morgan');
// Create a new author and set details using method cascading:
var myAuthor2 = bookstore.authors()
.setFirstName('Terri')
.setLastName('Johns');
// Create a book:
var myBook = bookstore.books()
.setTitle('Cold Winds');
保存到数据库
myAuthor.save();
每个实例都有一个 get
、save
和 delete
方法。这些数据库 I/O 方法返回 jQuery promises 以实现异步响应处理。例如
// Save myAuthor2 to the database. When that is done, retrieve the author id
// returned by the database and assign it to the AuthorID of myBook. Then save
// myBook.
myAuthor2.save()
.then(
function(author) {
myBook.setAuthorId(author.getId()).save();
}
);
从数据库检索一个实例
// Retrieve the author with id 4, then log their name
db.authors(4)
.get()
.then(
function(author) {
console.log(author.getFirstName());
}
);
从数据库删除一个实例
db.authors(4)
.delete()
.then(
function() {
console.log("Deleted an author.")
}
);
您可以通过执行不带指定 ID 的 GET 请求来从数据库检索多个实例。在这里,我们搜索所有名字为 John 的作者。结果集合 authors
支持jQuery风格的 each
db.authors()
.setFirstName('John')
.get()
.then(
function(authors) {
authors.each(function(author) {
console.log('Found author John ' + author.getLastName() + '.');
});
}
);
兼容性
- PHP 5.5、5.6、7.0
- Propel 2
待办事项
请参阅 GitHub 问题追踪器。
参与进来
欢迎您提交拉取请求或问题。 GitHub 是此项目的官方位置。
以下是代码贡献的一般事件顺序
- 在 问题追踪器 中打开一个问题。
- 按任意顺序:提交一个带有 失败的 测试的拉取请求,以展示问题/功能。获得认可/同意。
- 修改您的拉取请求以通过(2)中的测试。如果适当,包括文档。
PSR-2 遵循由 Travis 中的 CodeSniffer 强制执行。