Как преобразовать существующий файл библиотеки PHP, чтобы его можно было использовать в рамках CakePHP?

У меня есть эта библиотека в формате PHP не-Cake, обычный сценарий PHP, который в настоящее время работает как шарм. Мне нужно использовать это в рамках Cake. Файл библиотеки выглядит следующим образом: (пример извлечен)

<?php

// REST API functions

function sendAction($itemurl, $itemimageurl, $sessionid, $userid, $rating=""){

    global $someapiwebsiteURL, $apiKey, $tenantId;
    $somewebsiteAPI = $someapiwebsiteURL.$action."?apikey=".$apiKey.
                                                                 .....
                ................
    }


    //Codes extract


?>

Я сталкивался с несколькими способами сделать это. В настоящее время в замешательстве, как я собираюсь поместить этот файл библиотеки в мою платформу Cake?

  1. App:: импорт ()
  2. Источник данных

Функции из файла библиотеки выше (я предполагал, что он будет использоваться в одном из моих контроллеров для визуализации данных, выводимых через представление).

В настоящее время работает в структуре не-Cake Framework, страница просмотра выглядит так: (пример извлечен)

<?php
// my view page

$viewResponse = sendAction($itemdescription ,$itemurl , $itemimageurl,$sessionid,$userid);

//sample code only
?>

Оба файла работают нормально. Логика помещения его в структуру CakePHP - вот проблема. Кто-нибудь может предложить "способ" сделать это без чрезмерной работы с источником данных? Если нам нужно использовать источник данных в App/models/datasources/, то какова его структура? Как, например, в файле источника данных, мы включаем функции библиотеки? или это какой-то общий файл источника данных ReST, который можно найти здесь: Источник данных CakePHP ReST. Я просмотрел главу поваренной книги, посвященную источнику данных, и понимаю, что мы должны определить источник данных в нашем database.php, но если кто-то уверен в своем способе сделать это, используя метод datasource или app::import(), пожалуйста, поделитесь с подробнее?

ОБНОВИТЬ:

Привет, Лайонел! Спасибо за пополнение. Ну, на самом деле пользователи будут нажимать на действие вида: function view (){} в моем foods_controller. Я добавляю некоторые скрипты сюда, чтобы включить мою функцию просмотра в мой foods_controller, так что, возможно, это поможет вам легче помочь. Спасибо..

function view($id = null) {
        if (!$id) {
            $this->Session->setFlash(__('Invalid food', true));
            $this->redirect(array('action' => 'index'));
        }
        $this->set('food', $this->Food->read(null, $id));       
    }
  • Действие просмотра запускает функцию send_action (каждый раз, когда пользователь нажимает на страницу просмотра на контроллере продуктов). Поэтому каждый раз, когда пользователь нажимает на действие просмотра, его (динамические переменные): userid, sessionid, itemid этой страницы, url, itemdescription; (значение timerange является статическим строковым значением "ALL"), и, если оно есть (и т. д.), пока доступны только эти значения: Будет использоваться в качестве "параметров" в функции Send Action. То, что вы написали, близко к тому, что могут делать коды. Ты прав. Кроме того, что мы должны включить функцию Send Action внутри view () в контроллере пищевых продуктов?

  • Если мы посмотрим на динамическое заполнение переменных, упомянутых в пункте выше, не могли бы вы изменить свой второй код (например, код из вашего product_controller), чтобы он также работал для динамического получения переменных? (как вы спрашивали в последнем обновлении: как получить параметры..)

  • Просто чтобы было понятно.

    1. Пользователь просматривает страницу. Действие отправки собирает данные и отправляет их в API. (как мы уже сделали, вызвав функцию в библиотеке (ACME.php). * просто ожидая вашего обновления, если возможно, спасибо.
    2. В функции view () контроллера food: также есть дополнительный вызов. Второе призвание (2) это:

$recommendResponse = getRecommendations("otherusersviewed", $itemId, $userId);

Второе обращение вызывает файл библиотеки ACME.php, в котором есть вторая функция (2), которая извлекает данные, вот она: (она в рабочем состоянии, но ее просто нужно преобразовать в публичную статическую функцию, как вы делали для (1) первая функция. Не могли бы вы также помочь изменить этот код?:

function getRecommendations($recommendationType, $itemId, $userId){

    // sample code similar to the first one.
}

Вот и все. Кажется, в обычном формате PHP это довольно просто, и работает легко, но получить его на MVC framweork для некоторых немного сложно, для меня это очень сложно. Спасибо за помощь, Лайонел.:-)

PS Привет, Лайонел, я заметил, что что-то пропало в библиотеке после изменений? Посмотрите изначально у нас есть это:

$somewebsiteAPI = $someapiwebsiteURL.$action."?apikey=".$apiKey.

Смотри, переменные для $SomeWebsiteAPI а также $SomeApiWebsiteURL разные. Я что-то упустил? или ты модифицировал так, чтобы он был эффективнее? Я вижу, что переменная с именем $SomeWebsiteAPI модифицируется, чтобы стать переменной с именем $link? и переменная $SomeApiWebsiteURL изменяется на именованную переменную, $url, я прав? .. Спасибо.

Спасибо, с наилучшими пожеланиями. Джон Максим

1 ответ

Решение

Для меня, если у меня есть этот кусок кода, я бы сначала обернул его в статический (или нормальный) класс и назвал его ACME, затем я переместил бы acme.php в /apps/libs/acme.php, Тогда в контроллере буду использовать App::import('Lib', 'acme'), Это действие не делает ничего, кроме простого запроса файла, поэтому вы можете просто использовать его мгновенно, вызвав ACME::sendAction(...),

И относительно global Дело в том, что вам может потребоваться объявить статический (или нормальный) класс, а затем определить общие переменные как часть свойств класса, чтобы вы могли делиться ими со всеми функциями в классе.

Например, это /app/libs/acme.php

class ACME {

    private static $someapiwebsiteURL = "http://thewebsite/api/1.0/"; 
    private static $apiKey = "0010KIUMLA0PLQA665JJ";   
    private static $tenantId = "THE_TENANT_NAME";

    /**
     * Simple builder to build links from array of $params
     *
     * @param string $url The api url
     * @param array $params The given parameters
     * @return string built url
     */
    private static function BuildLink($url="", $params=array()) {

        $link = $url;
        foreach($params as $k=>$v) {
            $link .= "&$k=$v";
        }

        //Replace the first & to ?
        $link = preg_replace("/&/", "?", $link, 1);

        //Not sure if we need URL encode here, please uncomment this
        //if the API could not work.
        //$link = urlencode($link);

        return $link;
    }

    public static function SendAction($action, $itemId, $itemdescription, $itemurl, $itemimageurl, $sessionid, $userid, $rating="") {

        $somewebsiteAPI = self::BuildLink(self::$someapiwebsiteURL.$action, array(
            "apikey"=>self::$apiKey,
            "sessionid"=>$sessionid,
            "userid"=>$userid,
            "tenantid"=>self::$tenantId,
            "itemid"=>$itemId,
            "itemdescription"=>$itemdescription,
            "itemurl"=>$itemurl,
            "itemimageurl"=>$itemimageurl,

            /**
             * Assuming your API smart enough to only use this value when
             * the action is "rate"
             */
            "ratingvalue"=>$rating 
        ));

        $xml = simplexml_load_file($somewebsiteAPI);
        return $xml;
    }

    public static function GetRecommendations($recommendationType, $itemId, $userId) {
        $somewebsiteAPI = self::BuildLink(self::$someapiwebsiteURL.$recommendationType, array(
            'apikey'=>self::$apiKey,
            'tenantid'=>self::$tenantId,
            'itemid'=>$itemId,
            'userid'=>$userId
        ));

        $xml = simplexml_load_file($somewebsiteAPI);
        return $xml;
    }
}

И в вашем контроллере

App::import('Lib', 'acme');

class FoodController extends AppController {

    //Food is plural already I assume? You can just use
    //food, should be ok I think, else it will be weird
    //to use /foods/view/?
    var $name = "Food";
    var $uses = array("Item", "Food");

    function view($id="") {
        //We accepts only valid $id and $id > 0.
        //Take notes that this $id will be a string, not int.
        if (ctype_digit($id) && $id > 0) {


            //I don't know how you would gather the information, but I assume you
            //have a database with the information ready.

            //I assumed you have an `items` table
            $item = $this->Item->findById($id);

            $sessionid = "00988PPLO899223NHQQFA069F5434DB7EC2E34"; //$this->Session->...?
            $timeRange = "ALL";
            $userid = "24EH1725550099LLAOP3"; //$this->Auth->user('id')?

            if (!empty($item)) {
                $desc = $item['Item']['description'];
                $url = "/foods/view/".$id;
                $img = $item['Item']['img'];

                $viewResponse = ACME::SendAction("view", $id, $desc ,$url, $img, $sessionid, $userid);
                $this->set('food', $this->Food->read(null, $id));
            }else{
                $this->Session->setFlash(__('Invalid food', true));
                $this->redirect(array('action' => 'index'));
            }    
        }else{
            $this->Session->setFlash(__('Invalid food', true));
            $this->redirect(array('action' => 'index'));    
        }

    }

}

редактировать

Код был заполнен, и, конечно, без каких-либо гарантий:). Лично мне не очень нравятся длинные аргументы в функции (например, SendAction, ошибка удаления), лучше использовать более короткую, такую ​​как $params в ACME::BuildLink, Но просто чтобы уважать ваш код, я не сильно изменил SendAction метод.

Тогда я не совсем уверен, как вы будете использовать этот код, поэтому я предположил, что у вас есть ProductsControllerи как-то пользователь триггер URL, как /products/send_action/, Если вы сможете предоставить больше информации, мы сможем помочь.

Редактировать снова

Я изменил класс ACME, а также контроллер. Да, я пропускаю некоторые переменные, но я добавил их обратно в обновленный код.

Не слишком уверенный, если он будет работать (возможно, опечатка), вы можете просто изменить код, если он не работает для вас.

А для личных соглашений я обычно использую статические методы, такие как ACME:GetRecommendations или же ACME::SendAction,

О да, я лучше вернусь к переменным, которые вы использовали. Извините за их изменение, просто мне не нравятся длинные имена:)

И между прочим, корпорация ACME RoadRunner? Лол!

Ура Лайонел

Другие вопросы по тегам