Как преобразовать существующий файл библиотеки 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?
- App:: импорт ()
- Источник данных
Функции из файла библиотеки выше (я предполагал, что он будет использоваться в одном из моих контроллеров для визуализации данных, выводимых через представление).
В настоящее время работает в структуре не-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), чтобы он также работал для динамического получения переменных? (как вы спрашивали в последнем обновлении: как получить параметры..)
Просто чтобы было понятно.
- Пользователь просматривает страницу. Действие отправки собирает данные и отправляет их в API. (как мы уже сделали, вызвав функцию в библиотеке (ACME.php). * просто ожидая вашего обновления, если возможно, спасибо.
- В функции 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? Лол!
Ура Лайонел