我对PHP的知识比较平均(但是基本),但是我对PhalconPHP还是陌生的。我在浏览特定的在线课程网站时了解到PhalconPHP,并且该框架比其他PHP框架更快,更独特,并且它具有Micro
软件包,可以轻松开发REST API
。
就这样,我正在尝试学习如何在PhalconPHP Framework的帮助下开发API。而且,对于像我这样的初学者,我想开始使用raw SQL statements
而不是提供的phql syntax
,因为我并没有完全开发MVC应用程序(而且我确实有一个很难学习PHQL本身的整个概念,我需要一个单独的时间来学习。)
在处理多列查询结果时,我设法使工作正常,该结果映射到该类,就像使用PhalconPHP应该是这样,并带有以下示例代码:
<?php
namespace MyApplication\Db\ShortLinks\Services;
use MyApplication\Db\ShortLinks\DatabaseTables;
use Phalcon\Mvc\Model\Resultset\Simple as ResultSet;
class VisitorService
{
function getVisitorLogByLinkId($id)
{
$sqlQry = "SELECT * FROM visitors v WHERE v.link_id = $id ORDER BY v.visitor_id DESC;";
$visitor = new DatabaseTables\Visitor();
$resultSet = new ResultSet(null, $visitor, $visitor->getReadConnection()->query($sqlQry));
$data = [];
foreach ($resultSet as $result) {
$data[] = [
"visitor_name" => $result->visitor_name,
"access_timestamp" => $result->access_timestamp
];
}
return $data;
}
}
?>
但是,我似乎无法理解如何使用单列查询结果(例如获取SUM
,COUNT
甚至id和特定数据类型)来解决这个问题。在尝试重新创建提供的答案here时,我尝试了以下代码:
function isLinkIdValid($id)
{
$sqlQry = "SELECT IF(COUNT(l.link_id) = 0, 0, 1) 'is_exist' FROM links l WHERE l.link_id = $id;";
$result = $app->di->db->query($sqlQry);
$result->setFetchMode(Phalcon\Db::FETCH_ASSOC);
$result = $result->fetchAll($result);
return $result;
}
但是,正如我所期望的那样,由于无法从该函数访问$app
(Phalcon\Mvc\Micro
中的index.php
的实例)而无法工作。
最好向所有人解释,尽管我确实有models
个数据库表,但我已将所有数据库逻辑与模型对象分开,以保持其清洁并发挥其唯一作用-成为模型。我这样做的方法是创建一个名为/service
的新文件夹,并为其中的每个模型创建服务(例如:VisitorService
)。
要向所有人展示我的代码,我基本上在PhalconPHP's REST Tutorial之后对它进行了模式化,下面是我的代码段:
index.php :
<?php
use Phalcon\Loader;
use Phalcon\Mvc\Micro;
use Phalcon\Di\FactoryDefault;
use Phalcon\Db\Adapter\Pdo\Mysql as PdoMySql;
use Phalcon\Http\Response;
# Loader initialization and namespace registration
$loader = new Loader();
$loader->registerNamespaces([
"MyApplication\Db\ShortLinks\DatabaseTables" => __DIR__ . "/models/",
"MyApplication\Db\ShortLinks\Services" => __DIR__ . "/services/"
]);
$loader->register();
# DependencyInjector initialization and instantiation of database connection
$di = new FactoryDefault();
$di->set("db", function() {
return new PdoMySql([
"host" => "127.0.0.1",
"username" => "username",
"password" => "password",
"dbname" => "short_links"
]);
});
# Micro initialization, route definition
$app = new Micro($di);
$app->notFound(function() use ($app) {
$response = new Response();
$response->setStatusCode(404, "Not Found");
$response->setJsonContent([
"status" => 404,
"message" => "The specified route was not found, or does not exist",
"data" => ""
]);
return $response;
});
require "routes/visitor_route.php";
$app->handle();
?>
routes / visitor_route.php
<?php
use Phalcon\Http\Response;
use MyApplication\Db\ShortLinks\Services;
require "services/visitor_service.php";
$app->get('/v1/visitors/log/{id:[0-9]+}', function($id) use ($app) {
$response = new Response();
# validate id parameter
if($id <= 0) {
$response->setStatusCode(422, "Unprocessable Entity");
$response->setJsonContent([
"status" => 422,
"message" => "Invalid link id specified.",
"data" => ""
]);
return $response;
}
$service = new Services\VisitorService();
$response->setStatusCode(200, "OK");
$response->setJsonContent([
"status" => 200,
"message" => "",
"data" => $service->getVisitorLogByLinkId($id)
]);
# This partially works, except that it does not return whether a link id is valid, so I'm trying to create a logic for one.
// return $response;
$tempService = new Services\LinkService();
$tempResult = $tempService->isLinkIdValid($id);
return print_r($tempResult);
});
?>
service / visitor_service.php
<?php
namespace MyApplication\Db\ShortLinks\Services;
use MyApplication\Db\ShortLinks\DatabaseTables;
use Phalcon\Mvc\Model\Resultset\Simple as ResultSet;
class VisitorService
{
# technically belongs to 'services/link_service.php' but placed here to shorten attached codes.
function getAllLinks()
{
$sqlQry = "SELECT * FROM links;";
$link = new DatabaseTables\Link();
$resultSet = new ResultSet(null, $link, $link->getReadConnection()->query($sqlQry));
$data = [];
foreach ($resultSet as $result) {
$data[] = [
"link_id" => $result->link_id,
"description" => $result->description,
"original_url" => $result->original_url,
"short_url" => $result->short_url
];
}
return $data;
}
# technically belongs to 'services/link_service.php' but placed here to shorten attached codes.
function createNewShortLink($link)
{
$sqlQry = "INSERT INTO links VALUES (DEFAULT, '$link->description', '$link->original_url', $link->base_url, '$link->unique_key', DEFAULT, DEFAULT);";
$link = new DatabaseTables\Link();
$link->getReadConnection()->query($sqlQry);
}
# technically belongs to 'services/link_service.php' but placed here to shorten attached codes.
# This is the experimental code i am working with
function isLinkIdValid($id)
{
/*
As it is, everything here doesn't work.
*/
$sqlQry = "SELECT IF(COUNT(l.link_id) = 0, 0, 1) 'is_exist' FROM links l WHERE l.link_id = $id;";
$result = $app->di->db->query($sqlQry);
$result->setFetchMode(Phalcon\Db::FETCH_ASSOC);
$result = $result->fetchAll($result);
return $result;
}
function getVisitorLogByLinkId($id)
{
$sqlQry = "SELECT * FROM visitors v WHERE v.link_id = $id ORDER BY v.visitor_id DESC;";
$visitor = new DatabaseTables\Visitor();
$resultSet = new ResultSet(null, $visitor, $visitor->getReadConnection()->query($sqlQry));
$data = [];
foreach ($resultSet as $result) {
$data[] = [
"visitor_name" => $result->visitor_name,
"access_timestamp" => $result->access_timestamp
];
}
return $data;
}
}
?>
总而言之,我正在寻找一种使用RAW SQL Statements
内的PhalconPHP
从数据库中获取单列数据的方法。我已经挖掘了几种资源,但是如果没有的话,它们就很少了。
编辑1:我知道我如何实现服务并不完美,并且容易受到安全攻击。但请专注于主要问题。我稍后会解决其他问题。另外,我正在寻找的是能够使用$app->di["db"]
中存储在index.php
中的PdoMysql,就像我在getAllLinks()
和createNewShortLink($link)
函数中设法做到的那样。但是,我通过将PdoMysql对象从$app->di["db"]
传递给如下函数来提出了“临时”解决方案:
function isLinkIdValid($dbConn, $id)
{
$sqlQry = "SELECT IF(COUNT(l.link_id) = 0, 0, 1) 'is_exist' FROM links l WHERE l.link_id = $id;";
$isExist = $dbConn->fetchAll($sqlQry, \Phalcon\Db::FETCH_ASSOC);
return $isExist;
}