如何转换现有的 PHP 库文件以便可以在 CakePHP 框架中使用?

发布于 2024-10-14 00:10:06 字数 3168 浏览 3 评论 0原文

我有这个 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::import()
  2. 数据源

上面库文件中的函数(我认为它会在我的控制器之一中使用,以呈现通过视图输出的数据)。

目前工作在非Cake框架结构中,视图页面如下:(提取的示例)

<?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() 方法来完成它的方式,请与更多细节?

更新:

嗨,Lionel!,感谢您填写。好吧,实际上用户会点击我的 Foods_controller 中的视图操作:function view (){}。我在此处附加了一些脚本,以将我的视图函数包含在 food_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函数中的“参数”。您编写的内容与代码的功能很接近。你说得对。除了我们应该在食物控制器的 view() 中包含 Send Action 函数?

  • 如果我们考虑动态填充上面提到的变量,您能否修改您的第二个代码(例如来自您的product_controller 的代码),以便它也可以动态接收变量? (正如您在上次更新中所问的:如何获取参数..)

  • 只是为了说清楚。

    1. 用户查看该页面。发送操作收集数据并将其发送到 API。 (正如我们已经通过调用库中的函数 (ACME.php) 所做的那样。*如果可能的话,请等待您的更新,谢谢。
    2. 在食物控制器的 view() 函数中:还有一个额外的调用。 (2)第二个调用是这样的:

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

第二次调用调用 ACME.php 库文件,其中包含 (2)第二个检索数据的函数,这里是:(它处于工作状态,但只需要更改为公共静态函数,就像您对 (1)first 函数所做的那样。您也可以帮忙修改此代码吗?:

function getRecommendations($recommendationType, $itemId, $userId){
    
    // sample code similar to the first one.
}

这就是全部了。在普通的 PHP 格式中,它看起来很简单,而且工作起来很容易,但是对于某些人来说,将其移植到 MVC 框架上有点困难,对我来说非常感谢,Lionel :-)

PS。你好,Lionel,我注意到更改后库中缺少了一些内容?原来我们有这样的内容:

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

看,<的变量code>$SomeWebsiteAPI 和 $SomeApiWebsiteURL 是不同的。我错过了什么吗?或者您进行了修改,因此效率更高?我看到名为 $SomeWebsiteAPI 的变量被修改为名为 $link 的变量?变量 $SomeApiWebsiteURL 更改为命名变量 $url,对吗? .. 谢谢。

谢谢,最诚挚的问候。约翰·马克西姆

I have this library in PHP non-Cake format, the usual PHP scripting which currently works like a charm. I need to use this in a Cake framework. The library file is as follow: (example extracted)

<?php

// REST API functions

function sendAction($itemurl, $itemimageurl, $sessionid, $userid, $rating=""){
    
    global $someapiwebsiteURL, $apiKey, $tenantId;
    $somewebsiteAPI = $someapiwebsiteURL.$action."?apikey=".$apiKey.
                                                                 .....
                ................
    }
    

    //Codes extract


?>

I've come across a few ways of doing it. Currently confused, how am I going to place this library file into my Cake framework?

  1. App::import()
  2. Datasource

The functions in the library file above (I supposed it'd be used in one of my Controllers to render the data outputting through the view).

Currently working in a non-Cake framework structure, the view page is such as: (example extracted)

<?php
// my view page
 
$viewResponse = sendAction($itemdescription ,$itemurl , $itemimageurl,$sessionid,$userid);

//sample code only
?>

Both the files are working fine. The logic of putting it in a CakePHP framework is the problem here. Anyone may suggest "the" way of doing this without over-strenuously working on a data source? If we have to use a data source in App/models/datasources/, how exactly is the structure of it? Like, e.g., in datasource file, do we include the library functions? or is it some generic ReST datasource file which can be found here: CakePHP ReST datasource . I've gone through the cookbook chapter on datasource and understand we have to define the datasource in our database.php, but if someone is certain about their way of accomplishing it either using datasource or app::import() method, please share with more details?

UPDATE:

Hi Lionel!, thanks for filling up. Well, actually users will click on view action: function view (){} in my foods_controller. I'm appending some scripts here to include my view function in my foods_controller so maybe it may help you to help out easier. Thanks..

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));       
    }
  • The view action triggers the send_action function, (each time a user clicks on view page on foods controller). So each time, a user clicks on view action, his (dynamic variables): userid, sessionid, that page's itemid, url, itemdescription; (timerange value is a static string value "ALL"), and if any (etc.), so far only these values are available: Will be used as the "parameters" in the Send Action function. What you wrote is close to what the codes can do. You're right. Except we should include the Send Action function inside the view() in foods controller?

  • If we look at dynamically filling in the variables mentioned in the point above, could you modify your second code (the code from your product_controller, e.g.) so it also works to receive the variables dynamically? (as you asked in the last update: how to get the parameters..)

  • Just to make it clear.

    1. A user views the page. The send action collects data and send to the API. (as we've already done by calling the function in the library the (ACME.php). *just waiting for your update if possible, thanks.
    2. In the function view() of the foods controller: there's also an additional calling. The (2)second calling which is this:

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

The second calling calls the ACME.php library file in which there consists the (2)second function that retrieves data, here it is: (it's in working order, but just needs to be changed into a public static function like you did for the (1)first function. Could you help to modify this code too, please?:

function getRecommendations($recommendationType, $itemId, $userId){
    
    // sample code similar to the first one.
}

That's all to it. It seems quite simple in the normal PHP format, and it works easily, but getting it on an MVC framweork is a bit challenging for some, a lot for me. Thanks for helping out, Lionel. :-)

P.S. Hi Lionel, I notice something missing in the library after changes? Look originally we have this:

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

Look, the variables for $SomeWebsiteAPI and $SomeApiWebsiteURL are different. Did I miss out something? or you have modified so it is more efficient ? I see that the variable named $SomeWebsiteAPI is modified to become variable called $link ? and variable $SomeApiWebsiteURL is changed to the named variable, $url, am I right ? .. thanks.

Thanks, best regards. John Maxim

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

葬﹪忆之殇 2024-10-21 00:10:06

对我来说,如果我有这段代码,我会首先将其包装到静态(或普通)类中,并将其命名为 ACME,然后我会将 acme.php 移动到 /apps/libs/acme.php。然后在控制器中,我将使用 App::import('Lib', 'acme')。此操作仅需要文件,因此您可以通过调用 ACME::sendAction(...) 立即使用它。

对于全局事物,您可能只需要声明一个静态(或普通)类,然后将共享变量定义为类属性的一部分,这样您就可以在该类中的所有函数之间共享它们。班级。

例如,这是 /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'));    
        }

    }

}

Edit

代码已经被填满了,当然,没有任何保证:)。我个人不太喜欢在函数中使用长参数(例如 SendAction、错误修剪),而是使用较短的参数,例如 ACME 中的 $params: :构建链接。但为了尊重您的代码,我没有对 SendAction 方法进行太多修改。

然后我不太确定您将如何使用此代码,因此我假设您有一个 ProductsController,并且以某种方式用户触发网址如 /products/send_action/ 。如果您可以提供更多信息,我们将能够提供帮助。

再次编辑

我修改了 ACME 类以及控制器。是的,我确实错过了一些变量,但我已将它们添加回更新的代码中。

不太确定它是否有效(可能是拼写错误),如果它不适合您,您可以修改代码。

对于个人约定,我通常将静态方法大写,例如 ACME:GetRecommendationsACME::SendAction

哦,是的,我最好还是坚持使用您使用的变量。抱歉修改它们,只是我不喜欢长名字:)

顺便说一句,RoadRunner 的 ACME Corporation?哈哈!

干杯
莱昂内尔

To me, if I have this piece of code, I would first wrap it into a static (or normal) class, and named it ACME, then I will move the acme.php into /apps/libs/acme.php. Then in the controller, I will use App::import('Lib', 'acme'). This action do nothing but just requiring the file, so you can just use it instantly by calling ACME::sendAction(...).

And regarding the global thing, you might just need to declare a static (or normal) class, then define the shared variables as part of the class properties, so you can share them among all the functions in the class.

For example, this is the /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;
    }
}

And in your controller

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'));    
        }

    }

}

Edit

The code has been filled up, and of course, without any warranty :). I personally don't really like to have long arguments in a function (like SendAction, error prune), rather use shorter one like the $params in ACME::BuildLink. But just to respect your code, I didn't modify much on the SendAction method.

Then I'm not too sure how you would make use of this code, so I assumed you have a ProductsController, and somehow the user trigger url like /products/send_action/. If you can provide more information, then we would be able to help out.

Edit Again

I have modified the ACME class, as well as the controller. Yea I do miss out some variables, but I had added them back to the updated code.

Not too sure if it would work (perhaps typo), you can just modify the code if it doesn't work for you.

And for personal conventions, I usually capitalize methods which are static, like ACME:GetRecommendations or ACME::SendAction.

Oh yea, I better stick back to the variables you used. Sorry for modifying them, just I don't like long names :)

And btw, the RoadRunner's ACME Corporation? Lol!

Cheers
Lionel

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文