未定义的属性|使用两个类时出错

时间:2012-04-14 09:29:31

标签: php api class curl

我有以下两个班级:

第一类:

<?php

/**
 * Wrapper class for the Envato marketplaces API
*/ 


class envato_api_wrapper {

  protected   $api_key;
  protected   $cache_dir = 'cache';
  public      $cache_expires = 2;
  protected   $public_url = 'http://marketplace.envato.com/api/edge/set.json';


  public function __construct($api_key = null) {
    if ( isset($api_key) ) $this->api_key = $api_key; // allow the user to pass the API key upon instantiation
  }


 /**
  * Attach your API key. 
  *
  * @param string $api_key Can be accessed on the marketplaces via My Account 
  * -> My Settings -> API Key
  */
  public function set_api_key($api_key)
  {
     $this->api_key = $api_key;
  }


 /**
  * Retrieve the value of your API KEY, if needed.
  *
  * @return string The requested API Key.
  */
  public function get_api_key()
  {
     if ( ! isset($this->api_key) ) return 'No API Key is set.';
     return $this->api_key;
  }


 /**
  * Sets the cache directory for all API calls. 
  *
  * @param string $cache_dir 
  */
  public function set_cache_dir($cache_dir)
  {
     $this->cache_dir = $cache_dir;
  }


 /**
  * Retrieve the value of your cache directory, if needed.
  *
  * @return string The requested cache directory.
  */
  public function get_cache_dir()
  {
     return $this->cache_dir;
  }   


  /**
   * Available sets => 'vitals', 'earnings-and-sales-by-month', 'statement', 'recent-sales', 'account', 'verify-purchase', 'download-purchase'
   * 
   */ 
  public function private_user_data($user_name, $set, $purchase_code = null)
  {
     if ( ! isset($this->api_key) ) exit('You have not set an api key yet. $class->set_api_key(key)');
     if (! isset($set) ) return 'Missing parameters';

     $url = "http://marketplace.envato.com/api/edge/$user_name/$this->api_key/$set";
     if ( !is_null($purchase_code) ) $url .= ":$purchase_code";
     $url .= '.json';

     $result = $this->fetch($url);

     if ( isset($result->error) ) return 'Username, API Key, or purchase code is invalid.';
     return $result->$set;
  }


 /**
  * Can be used to verify if a person did in fact purchase your item.
  *
  * @param $user_name Author's username.
  * @param $purchase_code - The buyer's purchase code. See Downloads page for 
  * receipt.
  * @return object|bool If purchased, returns an object containing the details.
  */ 
  public function verify_purchase($user_name, $purchase_code)
  {
     $validity = $this->private_user_data($user_name, 'verify-purchase', $purchase_code);
     return isset($validity->buyer) ? $validity : false;
  }


 /**
  * Retrieve details for your most recent sales.
  *
  * @param string $user_name The username attached to your API KEY.
  * @param int $limit The number of sales to return.
  * @return array A list of your recent sales.
  */
  public function recent_sales($user_name, $limit = null)
  {
     $sales = $this->private_user_data($user_name, 'recent-sales');
     return $this->apply_limit($sales, $limit);
  }


 /**
  * Retrieve your account information -- balance, location, name, etc.
  *
  * @param string $user_name The username attached to your API KEY.
  * @return array A list of account information for the user.
  */
  public function account_information($user_name)
  {  
     $private_data = $this->private_user_data($user_name, 'account');
     return json_decode(json_encode($private_data), true);
  }


 /**
  * Grab quick monthly stats - number of sales, income, etc.
  *
  * @param string $user_name The username attached to your API KEY.
  * @param int $limit The number of months to return.
  * @return array A list of sales figures, ordered by month.
  */
  public function earnings_by_month($user_name, $limit = null)
  {
     $earnings = $this->private_user_data($user_name, 'earnings-and-sales-by-month');
     return $this->apply_limit($earnings, $limit);
  }


 /**
  * Generic method, to be used in combination with the marketplace API docs.
  *
  * @param string $user_name The user name of the seller to track.
  * @return array The returned data wrapped in an array.
  */
  public function public_user_data($user_name)
  {
     $url = preg_replace('/set/i', 'user:' . $user_name, $this->public_url);
     return $this->fetch($url, 'user');
  }


 /**
  * Retrieve the details for a specific marketplace item.
  *
  * @param string $item_id The id of the item you need information for. 
  * @return object Details for the given item.
  */
  public function item_details($item_id)
  {
     $url = preg_replace('/set/i', 'item:' . $item_id, $this->public_url);
     return $this->fetch($url, 'item');
  }


 /**
  * Similar to new_files, but focuses on a specific author's files.
  *
  * @param string $user_name The desired username.
  * @param string $marketplace_name The desired marketplace name.
  * @param int $limit The number of files to return.
  * @return array A list of recently added files by one user.
  */
  public function new_files_from_user($user_name, $marketplace_name = 'themeforest', $limit = null)
  {
     $cache_path = "$this->cache_dir/$user_name-$marketplace_name-new_files";

     $url = preg_replace('/set/i', 'new-files-from-user:' . $user_name . ',' . $marketplace_name, $this->public_url);

     return $this->apply_limit( $this->fetch($url, 'new-files-from-user'), $limit );
  }


  /**
  * Display the number of items the author has for sale by marketplace
  *
  * @param string $user_name The desired username.
  */
  public function user_items_by_site($user_name)
  {
     $cache_path = "$this->cache_dir/$user_name";

     $url = preg_replace('/set/i', 'user-items-by-site:' . $user_name, $this->public_url);

     return $this->fetch($url, 'user-items-by-site');
  }


 /**
  * Retrieves general marketplace member information.
  *
  * @param string $user_name The username to query.
  * @return object Contains the requested user information.
  */
  public function user_information($user_name)
  {
     $url = preg_replace('/set/i', 'user:' . $user_name, $this->public_url);
     return $this->fetch($url, 'user');
  }


  /*
  * Either fetches the desired data from the API and caches it, or fetches the cached version
  *
  * @param string $url The url to the API call
  * @param string $set (optional) The name of the set to retrieve. 
  */
  protected function fetch($url, $set = null) 
  {
     // Use the API url to generate the cache file name. 
     // So: http://marketplace.envato.com/api/edge/collection:739793.json
     // Becomes: collection-739793.json
     $cache_path = $this->cache_dir . '/' . str_replace(':', '-', substr(strrchr($url, '/'), 1));

     if ( $this->has_expired($cache_path) ) {
        // get fresh copy
        $data = $this->curl($url);

        if ($data) {
           $data = isset($set) ? $data->{$set} : $data; // if a set is needed, update
        } else exit('Could not retrieve data.');

        $this->cache_it($cache_path, $data);

        return $data;
     } else {
        // if available in cache, use that
        return json_decode(file_get_contents($cache_path));
     }
  }


 /**
  * Filters returned result, according to the supplied $limit.
  *
  * @param string $orig_arr The original array to work on.
  * @param int $limit Specifies the number of array items in the result.
  * @return array A new array with a count equal to the passed $limit.
  */
  public function apply_limit($orig_arr, $limit)
  {
     if ( !is_int($limit) ) return $orig_arr;

     // Make sure that there are enough items to filter through... 
     if ( $limit > count($orig_arr) ) $limit = count($orig_arr);

     $new_arr = array();
     for ( $i = 0; $i <= $limit - 1; $i++ ) {
        $new_arr[] = $orig_arr[$i];
     }
     return $new_arr;
  }


 /**
  * General purpose function to query the marketplace API.
  *
  * @param string $url The url to access, via curl.
  * @return object The results of the curl request.
  */
  protected function curl($url) 
  {
     if ( empty($url) ) return false;

     $ch = curl_init($url);
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

     $data = curl_exec($ch);
     curl_close($ch);

     $data = json_decode($data);

     return $data; // string or null
  }


  /*
  * Caches the results request to keep from hammering the API
  *
  * @param string $cache_path - A path to the cache file
  * @param string $data - The results from the API call - should be encoded
  */
  protected function cache_it($cache_path, $data)
  {
     if ( !isset($data) ) return;
     !file_exists($this->cache_dir) && mkdir($this->cache_dir);
     file_put_contents( $cache_path, json_encode($data) );

     return $cache_path;
  }


  /*
  * Determines whether the provided file has expired yet 
  *
  * @param string $cache_path The path to the cached file
  * @param string $expires - In hours, how long the file should cache for.
  */
  protected function has_expired($cache_path, $expires = null) 
  {
     if ( !isset($expires) ) $expires = $this->cache_expires;

     if ( file_exists($cache_path) ) {
        return time() - $expires * 60 * 60 > filemtime($cache_path);
     }

     return true;
  }


  /*
  * Helper function that deletes all of the files in your cache directory.
  */
  public function clear_cache(){
     array_map('unlink', glob("$this->cache_dir/*"));
   }
}

第二类:

<?php

/**
* Operation Class for Envato API Wrapper
*/

class envato_api_class {

    protected   $api_key;
    protected   $username;
    public      $envato_api_wrapper;
    public      $path_to_envato_api_wrapper;


    public function __construct($api_key = null, $username = null) {
        if ( isset($api_key) ) {
            $this->api_key = $api_key;
        } elseif ( isset($username) ) {
            $this->username = $username;
        }
        $this->path_to_envato_api_wrapper = 'envato_api_wrapper.php';
        require($this->path_to_envato_api_wrapper);
        $this->envato_api_wrapper = new envato_api_wrapper($api_key);
    }

    public function get_all_items_by_site() {
        $items_by_marketplace = $this->envato_api_wrapper->user_items_by_site($this->username);
        $marketplaces = array();
        foreach ($items_by_marketplace as $key) {
            $marketplaces[] = array(
                'Marketplace'  => $key->site,
                'Items'        => $key->items
            );
        }
        foreach ($marketplaces as $key) {
            $items[$key['Marketplace']] = $this->envato_api_wrapper->new_files_from_user($this->username, $key['Marketplace']);
        }
        return json_decode(json_encode($items), true);
    }

    public function get_all_items() {
        $items_by_marketplace = $this->envato_api_wrapper->user_items_by_site($this->username);
        $marketplaces = array();
        $items = array();
        $item = array();
        foreach ($items_by_marketplace as $key) {
            $marketplaces[] = array(
                'Marketplace'  => $key->site,
                'Items'        => $key->items
            );
        }
        foreach ($marketplaces as $key) {
            $items[$key['Marketplace']] = $this->envato_api_wrapper->new_files_from_user($this->username, $key['Marketplace']);
        }
        foreach ($items as $main_key) {
            foreach ($main_key as $secondary_key) {
                $item[] = array(
                    'ID'        => $secondary_key->id,
                    'Item'      => $secondary_key->item,
                    'URL'       => $secondary_key->url,
                    'User'      => $secondary_key->user,
                    'Thumb'     => $secondary_key->thumbnail,
                    'Sales'     => $secondary_key->sales,
                    'Rating'    => $secondary_key->rating,
                    'Cost'      => $secondary_key->cost,
                    'Uploaded'  => $secondary_key->uploaded_on,
                    'Tags'      => $secondary_key->tags,
                    'Category'  => $secondary_key->category,
                    'Preview'   => $secondary_key->live_preview_url
                );
            }
        }
        return $item;
    }

}

?>

我正在尝试在另一个文件中执行以下代码,这三个级别位于类所在的位置:

<?php

                require 'assets/class/envato/envato_api_class.php';

                $api_key = 'some_key_here';

                $username = 'some_username_here';

                $envato = new envato_api_class($api_key, $username);

                $items = $envato->get_all_items();

                function rating($cluster) {
                    for ($i = 1; $i <= $cluster; $i++) {
                        echo '<img src="assets/gfx/filled-star.png" alt="Rating" />';
                    }
                    $empty = 5 - $cluster;
                    if ($empty > 0) {
                        for ($i = 0; $i < $empty; $i++) {
                            echo '<img src="assets/gfx/empty-star.png" alt="Rating" />';
                        }
                    }
                }

                // Adding Rows instead of altogether...
                $halfway = floor(count($items)/2);
                $count=0;

                echo '<div class="item-row">';

                foreach ($items as $key) {

                    // Check if we can add the second row
                    if($count==$halfway){
                        echo '</div><div class="item-row">';
                    }
                    $count++;

                    echo '<div class="product id-'.$key['ID'].'">';
                        echo '<div class="description">';
                            echo '<div class="thumb">';
                                echo '<i class="icon"><img src="'.$key['Thumb'].'" alt="Thumb"/><span class="preview" data-image-link="'.$key['Preview'].'"><img src="assets/gfx/zoom-icon.png" alt="Zoom"/></span></i>';
                            echo '</div>';
                            echo '<div class="info">';
                                echo '<div class="sales">';
                                    echo '<div class="icon">';
                                        echo '<img src="assets/gfx/sales-icon.png" alt="Sales Icon"/>';
                                    echo '</div>';
                                    echo '<div class="text">';
                                        echo '<p>'.$key['Sales'].'</p>';
                                    echo '</div>';
                                echo '</div>';
                                echo '<div class="rating">';
                                    rating($key['Rating']);
                                echo '</div>';
                            echo '</div>';
                        echo '</div>';

                        echo '<div class="purchase">';
                            echo '<div class="info">';
                                echo '<i class="icon"><span class="tooltip">$ '.$key['Cost'].'</span></i>';
                            echo '</div>';
                            echo '<div class="proceed">';
                                echo '<a class="button" href="'.$key['URL'].'?ref='.$username.'">Purchase</a>';
                            echo '</div>';
                        echo '</div>';
                    echo '</div>';
                }

                echo '</div>'; // End Item Row
            ?>

但是在localhost上测试时出现以下错误:

Notice: Undefined property: stdClass::$user-items-by-site in C:\xampp\htdocs\Envato\assets\class\envato\envato_api_wrapper.php on line 233

有人能告诉我为什么会收到这个错误?我在那里做错了什么?

1 个答案:

答案 0 :(得分:2)

由于这一行(198),你得到了这个错误:

return $this->fetch($url, 'user-items-by-site');

与第233行结合使用:

$data = isset($set) ? $data->{$set} : $data; // if a set is needed, update

您显然正在尝试访问不存在的成员。

因为数据来自远程源,然后被解析为JSON,我们可能无法提供更多帮助。