【问题标题】:Call to undefined function that isn't undefined?调用未定义的未定义函数?
【发布时间】:2012-02-29 02:18:52
【问题描述】:

所以,当我尝试运行这行代码时,我收到以下错误:

致命错误:在第 58 行的 /Applications/XAMPP/xamppfiles/htdocs/CI/application/libraries/Shopify.php 中调用未定义函数 curl_http_api_request_()

其中第 58 行就是这一行:

$response = curl_http_api_request_($method, $url, $query, $payload, $request_headers, $response_headers);

我不太确定为什么它不能调用第二个函数。代码如下。我不知道问题是什么。

class Shopify
{
public $_api_key;
public $_shared_secret;
public $CI; // To hold the CI superglobal



public function __construct ()
{
    $this->_assign_libraries(); // Loads the CI superglobal and loads the config into it

    // Get values from the CI config
    $this->_api_key                     = $this->CI->config->item('api_key', 'shopify');
    $this->_shared_secret               = $this->CI->config->item('shared_secret', 'shopify');
}

public function shopify_app_install_url($shop_domain)
{
    return "http://$shop_domain/admin/api/auth?api_key=". $this->_api_key;
}


public function shopify_is_app_installed($shop, $t, $timestamp, $signature)
{
    return (md5($this->_shared_secret . "shop={$shop}t={$t}timestamp={$timestamp}") === $signature);
}


public function shopify_api_client($shops_myshopify_domain, $shops_token, $private_app=false)
{
    $password = $private_app ? $this->_shared_secret : md5($this->_shared_secret.$shops_token);
    $baseurl = "https://" . $this->_api_key . ":$password@$shops_myshopify_domain/";

    return function ($method, $path, $params=array(), &$response_headers=array()) use ($baseurl)
    {
        $url = $baseurl.ltrim($path, '/');
        $query = in_array($method, array('GET','DELETE')) ? $params : array();
        $payload = in_array($method, array('POST','PUT')) ? stripslashes(json_encode($params)) : array();
        $request_headers = in_array($method, array('POST','PUT')) ? array("Content-Type: application/json; charset=utf-8", 'Expect:') : array();

        $response = curl_http_api_request_($method, $url, $query, $payload, $request_headers, $response_headers);
        $response = json_decode($response, true);

        if (isset($response['errors']) or ($response_headers['http_status_code'] >= 400))
            throw new ShopifyApiException(compact('method', 'path', 'params', 'response_headers', 'response', 'shops_myshopify_domain', 'shops_token'));

        return (is_array($response) and (count($response) > 0)) ? array_shift($response) : $response;
    };
}

    public function curl_http_api_request_($method, $url, $query='', $payload='', $request_headers=array(), &$response_headers=array())
    {
        $url = curl_append_query_($url, $query);
        $ch = curl_init($url);
        curl_setopts_($ch, $method, $payload, $request_headers);
        $response = curl_exec($ch);
        $errno = curl_errno($ch);
        $error = curl_error($ch);
        curl_close($ch);

        if ($errno) throw new ShopifyCurlException($error, $errno);

        list($message_headers, $message_body) = preg_split("/\r\n\r\n|\n\n|\r\r/", $response, 2);
        $response_headers = $this->curl_parse_headers_($message_headers);

        return $message_body;
    }

        private function curl_append_query_($url, $query)
        {
            if (empty($query)) return $url;
            if (is_array($query)) return "$url?".http_build_query($query);
            else return "$url?$query";
        }

        private function curl_setopts_($ch, $method, $payload, $request_headers)
        {
            curl_setopt($ch, CURLOPT_HEADER, true);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
            curl_setopt($ch, CURLOPT_MAXREDIRS, 3);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
            curl_setopt($ch, CURLOPT_USERAGENT, 'HAC');
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
            curl_setopt($ch, CURLOPT_TIMEOUT, 30);

            if ('GET' == $method)
            {
                curl_setopt($ch, CURLOPT_HTTPGET, true);
            }
            else
            {
                curl_setopt ($ch, CURLOPT_CUSTOMREQUEST, $method);
                if (!empty($request_headers)) curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers);
                if (!empty($payload))
                {
                    if (is_array($payload)) $payload = http_build_query($payload);
                    curl_setopt ($ch, CURLOPT_POSTFIELDS, $payload);
                }
            }
        }

        private function curl_parse_headers_($message_headers)
        {
            $header_lines = preg_split("/\r\n|\n|\r/", $message_headers);
            $headers = array();
            list(, $headers['http_status_code'], $headers['http_status_message']) = explode(' ', trim(array_shift($header_lines)), 3);
            foreach ($header_lines as $header_line)
            {
                list($name, $value) = explode(':', $header_line, 2);
                $name = strtolower($name);
                $headers[$name] = trim($value);
            }

            return $headers;
        }


public function shopify_calls_made($response_headers)
{
    return shopify_shop_api_call_limit_param_(0, $response_headers);
}

public function shopify_call_limit($response_headers)
{
    return shopify_shop_api_call_limit_param_(1, $response_headers);
}

public function shopify_calls_left($response_headers)
{
    return shopify_call_limit($response_headers) - shopify_calls_made($response_headers);
}

    private function shopify_shop_api_call_limit_param_($index, $response_headers)
    {
        $params = explode('/', $response_headers['http_x_shopify_shop_api_call_limit']);
        return (int) $params[$index];
    }


/**
 * Shopify::_assign_libraries()
 *
 * Grab everything from the CI superobject that we need
 */
 public function _assign_libraries()
 {

        $this->CI =& get_instance();


        $this->CI->load->config('shopify', TRUE);

        return;

 }

更新: 这整行是由我调用这行代码开始的:

$shopify = $this->shopify->shopify_api_client($shops_myshopify_domain, $shops_token);

我还更新了上面的代码以包含整个文件。

【问题讨论】:

  • 由于方法/函数在一个类中,您需要声明例如$response = $this->curl_http_api_request_(....)
  • @LawrenceCherone:我认为您应该将其发布为答案。 :-)
  • $this 不好,因为它会引发此错误:致命错误:不在对象上下文中使用 $this。匿名函数有自己的上下文,所以你不能在里面使用 $this...
  • 在下面查看我的答案。我测试了这段代码,它可以工作。

标签: php codeigniter curl shopify


【解决方案1】:

您只能通过将 $this 作为对象传递给匿名函数来实现它,因为它有自己的上下文:

class example {
    public function trigger() {
        $func = $this->func();
        $func($this);
    }

    public function func() {
        return function($obj) {
            $obj->inner();
        };
    }

    public function inner() {
        die('inside inner');
    }
}

$obj = new example();
$obj->trigger();

编辑:所以针对您的问题:

  1. 改变这一行:

    返回函数($method, $path, $params=array(), &$response_headers=array()) 使用($baseurl)

进入这个:

return function ($instance, $method, $path, $params=array(), &$response_headers=array()) use ($baseurl)
  1. 在匿名函数内部更改这一行:

    $response = curl_http_api_request_($method, $url, $query, $payload, $request_headers, $response_headers);

进入这个:

$response = $instance->curl_http_api_request_($method, $url, $query, $payload, $request_headers, $response_headers);
  1. 现在 shopify_api_client 函数将返回此匿名函数且没有错误:

    $shopify = $this->shopify->shopify_api_client($shops_myshopify_domain, $shops_token);

  2. 你需要这样调用这个函数:

    $shopify($this->shopify, ... 以及匿名函数需要的其余参数 ...);

现在清楚了吗?我从来没有用过shopify,但它应该工作的一般方式就像我写的那样。

【讨论】:

  • 我更新后你能看一下代码吗?我不知道我是否完全理解您的回答,并且我认为附加代码使我想要做的事情更加清晰。
  • FYI in PHP5.4 $this 在匿名函数中可用:php.net/manual/en/functions.anonymous.php(在更新日志下)
  • @MikeB 我不在 PHP5.4 上,所以我确实收到错误:致命错误:不在对象上下文中使用 $this
  • 查看我的编辑,希望对您有所帮助! @MikeB - 谢谢 - 我不知道 PHP 5.4 对此做了什么。您是否在返回后尝试 $this 在函数之外工作?
  • 好吧,我花了一点时间来理解这一切,但我想我现在明白了!正如你所说,它似乎正在返回函数。非常感谢帮忙。现在要弄清楚它返回的这个新错误意味着什么!
【解决方案2】:

如果您从类外部访问方法,则需要声明它,如果您从类内部访问方法,则需要使用$this->methodname()

<?php
class shopify_api{
    ...

    ...

    ...
    public function curl_http_api_request_($method, $url, $query='', $payload='', $request_headers=array(), &$response_headers=array())
    {
        $url = curl_append_query_($url, $query);
        $ch = curl_init($url);
        curl_setopts_($ch, $method, $payload, $request_headers);
        $response = curl_exec($ch);
        $errno = curl_errno($ch);
        $error = curl_error($ch);
        curl_close($ch);

        if ($errno) throw new ShopifyCurlException($error, $errno);

        list($message_headers, $message_body) = preg_split("/\r\n\r\n|\n\n|\r\r/", $response, 2);
        $response_headers = $this->curl_parse_headers_($message_headers);

        return $message_body;
    }

}

$shopify = new shopify_api();
//--------V
$response=$shopify->curl_http_api_request_();
?>


由于您更新了问题,您是否尝试过更改:
$shopify = $this->shopify->shopify_api_client($shops_myshopify_domain, $shops_token);

也是:(因为您似乎添加了额外的 shopify 属性,我无法从您的代码中看到您在哪里设置并注入了您的方法)

$shopify = $this->shopify_api_client($shops_myshopify_domain, $shops_token);

【讨论】:

  • 如果有人知道 $shopify 在附加类时会被归类为什么,请告诉我,它仍然被称为变量吗?大声笑它是一个变量对象,对大声笑
  • 也许我没有提供足够的信息。我先调用一个不同的函数。我会更新原帖。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-24
  • 2016-10-11
  • 2018-01-31
  • 2013-09-11
  • 2013-01-26
相关资源
最近更新 更多