У меня относительно средние (хотя и базовые) знания по PHP, но я довольно плохо знаком с PhalconPHP .Я узнал о PhalconPHP, просматривая веб-сайт определенного онлайн-курса, и что этот фреймворк довольно быстрый и уникальный, чем другие PHP-фреймворки, плюс он имеет пакет Micro
для простой разработки REST API
.
Я пытаюсь узнать, как разработать API с помощью PhalconPHP Framework.И для начинающих, таких как я, я хотел бы начать с использования 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
,или даже идентификаторы и конкретный тип данных.Я попробовал приведенный ниже код, поскольку пытался воссоздать предоставленный ответ здесь :
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
).
Чтобы показать всем свой код, я в основномскопировал его после учебника REST PhalconPHP , ниже приведен фрагмент моего кода:
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();
?>
маршруты/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: я знаю, что то, как я реализовал сервис, не идеально, и это подвержено атакам безопасности.но, пожалуйста, сосредоточьтесь на главной проблеме вопроса.я решу другие вопросы потом.Кроме того, я ищу возможность использовать PdoMysql, хранящийся в $app->di["db"]
из index.php
, так же, как мне это удалось в 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;
}