PhalconPHP - как вернуть возвращаемый однотипный результат оператора Raw SQL - PullRequest
0 голосов
/ 08 апреля 2019

У меня относительно средние (хотя и базовые) знания по 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;
}
...