2011-05-20 58 views
0

我已經下載了PayPal API (SOAP) for PHPPHP:「無法重新聲明課程...」,即使我更改了課程名稱

我得到這個錯誤:

Fatal error: Cannot redeclare class SOAP_Client in /home/me/app1/plugins/mbpPlatformFrontendPlugin/lib/paypal/PayPal/SOAP/Client.php on line 83

奇怪的是:如果我改變類來還有什麼有史以來名稱,例如SOAP_Client_foo,我得到

Fatal error: Cannot redeclare class SOAP_Client_foo in /home/me/app1/plugins/mbpPlatformFrontendPlugin/lib/paypal/PayPal/SOAP/Client.php on line 83

有什麼想法?

<?php 
// 
// +----------------------------------------------------------------------+ 
// | PHP Version 4              | 
// +----------------------------------------------------------------------+ 
// | Copyright (c) 1997-2003 The PHP Group        | 
// +----------------------------------------------------------------------+ 
// | This source file is subject to version 2.02 of the PHP license,  | 
// | that is bundled with this package in the file LICENSE, and is  | 
// | available at through the world-wide-web at       | 
// | http://www.php.net/license/2_02.txt.         | 
// | If you did not receive a copy of the PHP license and are unable to | 
// | obtain it through the world-wide-web, please send a note to   | 
// | [email protected] so we can mail you a copy immediately.    | 
// +----------------------------------------------------------------------+ 
// | Authors: Shane Caraveo <[email protected]> Port to PEAR and more | 
// | Authors: Dietrich Ayala <[email protected]> Original Author   | 
// +----------------------------------------------------------------------+ 
// 
// $Id: Client.php,v 1.1.1.1 2006/02/19 08:15:20 dennis Exp $ 
// 

//require_once 'PayPal/SOAP/Value.php'; 
//require_once 'PayPal/SOAP/Base.php'; 
//require_once 'PayPal/SOAP/Transport.php'; 
//require_once 'PayPal/SOAP/WSDL.php'; 
//require_once 'PayPal/SOAP/Fault.php'; 
//require_once 'PayPal/SOAP/Parser.php'; 
//require_once 'PayPal/SOAP/PatternReplace.php'; 

// Arnaud: the following code was taken from DataObject 
// and adapted to suit 

// this will be horrifically slow!!!! 
// NOTE: Overload SEGFAULTS ON PHP4 + Zend Optimizer 
// these two are BC/FC handlers for call in PHP4/5 

if (!class_exists('SOAP_Client_Overload')) { 
    if (substr(phpversion(), 0, 1) == 5) { 
     class SOAP_Client_Overload extends SOAP_Base 
     { 
      function __call($method, $args) 
      { 
       $return = null; 
       $this->_call($method, $args, $return); 
       return $return; 
      } 
     } 
    } else { 
     if (!function_exists('clone')) { 
      eval('function clone($t) { return $t; }'); 
     } 
     eval(' 
      class SOAP_Client_Overload extends SOAP_Base 
      { 
       function __call($method, $args, &$return) 
       { 
        return $this->_call($method, $args, $return); 
       } 
      }'); 
    } 
} 

/** 
* SOAP Client Class 
* 
* This class is the main interface for making soap requests. 
* 
* basic usage: 
* $soapclient = new SOAP_Client(string path [ , boolean wsdl]); 
* echo $soapclient->call(string methodname [ , array parameters]); 
* 
* Originally based on SOAPx4 by Dietrich Ayala 
* http://dietrich.ganx4.com/soapx4 
* 
* @access public 
* @package SOAP::Client 
* @author Shane Caraveo <[email protected]> Conversion to PEAR and updates 
* @author Stig Bakken <[email protected]> Conversion to PEAR 
* @author Dietrich Ayala <[email protected]> Original Author 
*/ 
class SOAP_Client extends SOAP_Client_Overload 
{ 
    /** 
    * Communication endpoint. 
    * 
    * Currently the following transport formats are supported: 
    * - HTTP 
    * - SMTP 
    * 
    * Example endpoints: 
    * http://www.example.com/soap/server.php 
    * https://www.example.com/soap/server.php 
    * mailto:[email protected] 
    * 
    * @var string 
    * @see SOAP_Client() 
    */ 
    public $_endpoint = ''; 

    /** 
    * portname 
    * 
    * @var string contains the SOAP PORT name that is used by the client 
    */ 
    public $_portName = ''; 

    /** 
    * Endpoint type 
    * 
    * @var string e.g. wdsl 
    */ 
    public $__endpointType = ''; 

    /** 
    * wire 
    * 
    * @var string contains outoing and incoming data stream for debugging. 
    */ 
    public $xml; // contains the received xml 
    public $wire; 
    public $__last_request = null; 
    public $__last_response = null; 

    /** 
    * Options 
    * 
    * @var array 
    */ 
    public $__options = array('trace'=>0); 

    /** 
    * encoding 
    * 
    * @var string Contains the character encoding used for XML parser, etc. 
    */ 
    public $_encoding = SOAP_DEFAULT_ENCODING; 

    /** 
    * headersOut 
    * 
    * @var array contains an array of SOAP_Headers that we are sending 
    */ 
    public $headersOut = null; 

    /** 
    * headersOut 
    * 
    * @var array contains an array headers we recieved back in the response 
    */ 
    public $headersIn = null; 

    /** 
    * __proxy_params 
    * 
    * @var array contains options for HTTP_Request class (see HTTP/Request.php) 
    */ 
    public $__proxy_params = array(); 

    public $_soap_transport = null; 

    /** 
    * SOAP_Client constructor 
    * 
    * @param string endpoint (URL) 
    * @param boolean wsdl (true if endpoint is a wsdl file) 
    * @param string portName 
    * @param array contains options for HTTP_Request class (see HTTP/Request.php) 
    * @access public 
    */ 
    function SOAP_Client($endpoint, $wsdl = false, $portName = false, $proxy_params=array()) 
    { 
     parent::SOAP_Base('Client'); 
     $this->_endpoint = $endpoint; 
     $this->_portName = $portName; 
     $this->__proxy_params = $proxy_params; 

     $wsdl = $wsdl ? $wsdl : strcasecmp('wsdl', substr($endpoint, strlen($endpoint) - 4)) == 0; 

     // make values 
     if ($wsdl) { 
      $this->__endpointType = 'wsdl'; 
      // instantiate wsdl class 
      $this->_wsdl = new SOAP_WSDL($this->_endpoint, $this->__proxy_params); 
      if ($this->_wsdl->fault) { 
       $this->_raiseSoapFault($this->_wsdl->fault); 
      } 
     } 
    } 

    function _reset() 
    { 
     $this->xml = null; 
     $this->wire = null; 
     $this->__last_request = null; 
     $this->__last_response = null; 
     $this->headersIn = null; 
     $this->headersOut = null; 
    } 

    /** 
    * setEncoding 
    * 
    * set the character encoding, limited to 'UTF-8', 'US_ASCII' and 'ISO-8859-1' 
    * 
    * @param string encoding 
    * @return mixed returns null or SOAP_Fault 
    * @access public 
    */ 
    function setEncoding($encoding) 
    { 
     if (in_array($encoding, $this->_encodings)) { 
      $this->_encoding = $encoding; 
      return null; 
     } 
     return $this->_raiseSoapFault('Invalid Encoding'); 
    } 

    /** 
    * addHeader 
    * 
    * To add headers to the envelop, you use this function, sending it a 
    * SOAP_Header class instance. 
    * 
    * @param SOAP_Header a soap value to send as a header 
    * @access public 
    */ 
    function addHeader(&$soap_value) 
    { 
     # add a new header to the message 
     if (is_a($soap_value,'soap_header')) { 
      $this->headersOut[] =& $soap_value; 
     } else if (gettype($soap_value) == 'array') { 
      // name, value, namespace, mustunderstand, actor 
      $this->headersOut[] = new SOAP_Header($soap_value[0], null, $soap_value[1], $soap_value[2], $soap_value[3]);; 
     } else { 
      $this->_raiseSoapFault("Don't understand the header info you provided. Must be array or SOAP_Header."); 
     } 
    } 

    /** 
    * SOAP_Client::call 
    * 
    * the namespace parameter is overloaded to accept an array of 
    * options that can contain data necessary for various transports 
    * if it is used as an array, it MAY contain a namespace value and a 
    * soapaction value. If it is overloaded, the soapaction parameter is 
    * ignored and MUST be placed in the options array. This is done 
    * to provide backwards compatibility with current clients, but 
    * may be removed in the future. 
    * 
    * @param string method 
    * @param array params 
    * @param array options (hash with namespace, soapaction, timeout, from, subject, etc.) 
    * 
    * The options parameter can have a variety of values added. The currently supported 
    * values are: 
    * namespace 
    * soapaction 
    * timeout (http socket timeout) 
    * from (smtp) 
    * transfer-encoding (smtp, sets the Content-Transfer-Encoding header) 
    * subject (smtp, subject header) 
    * headers (smtp, array-hash of extra smtp headers) 
    * 
    * @return array of results 
    * @access public 
    */ 
    function &call($method, &$params, $namespace = false, $soapAction = false) 
    { 
     $this->headersIn = null; 
     $this->__last_request = null; 
     $this->__last_response = null; 
     $this->wire = null; 
     $this->xml = null; 

     $soap_data =& $this->__generate($method, $params, $namespace, $soapAction); 
     if (PEAR::isError($soap_data)) { 
      return $this->_raiseSoapFault($soap_data); 
     } 

     // __generate may have changed the endpoint if the wsdl has more 
     // than one service, so we need to see if we need to generate 
     // a new transport to hook to a different URI. Since the transport 
     // protocol can also change, we need to get an entirely new object, 
     // though this could probably be optimized. 
     if (!$this->_soap_transport || $this->_endpoint != $this->_soap_transport->url) { 
      $this->_soap_transport =& SOAP_Transport::getTransport($this->_endpoint); 
      if (PEAR::isError($this->_soap_transport)) { 
       $fault =& $this->_soap_transport; 
       $this->_soap_transport = null; 
       return $this->_raiseSoapFault($fault); 
      } 
     } 
     $this->_soap_transport->encoding = $this->_encoding; 

     // Send the message. 
     $transport_options = array_merge_recursive($this->__proxy_params, $this->__options); 

     // This is to replace "_" by "-" since wsdl has "-" and not "_" (see NOTE in Readme.html) 
     if(file_exists(dirname(__FILE__) . '/PatternReplace.php')){ 
       $soap_data = underscore_replace($soap_data); 
     } 

     $this->xml =& $this->_soap_transport->send($soap_data, $transport_options); 

     // Save the wire information for debugging. 
     if ($this->__options['trace'] > 0) { 
      $this->__last_request =& $this->_soap_transport->outgoing_payload; 
      $this->__last_response =& $this->_soap_transport->incoming_payload; 
      $this->wire =& $this->__get_wire(); 
     } 
     if ($this->_soap_transport->fault) { 
      return $this->_raiseSoapFault($this->xml); 
     } 

     $this->__attachments =& $this->_soap_transport->attachments; 
     $this->__result_encoding = $this->_soap_transport->result_encoding; 

     if (isset($this->__options['result']) && $this->__options['result'] != 'parse') { 
      return $this->xml; 
     } 

     return $this->__parse($this->xml, $this->__result_encoding, $this->__attachments); 
    } 

    /** 
    * Sets option to use with the transports layers. 
    * 
    * An example of such use is 
    * $soapclient->setOpt('curl', CURLOPT_VERBOSE, 1) 
    * to pass a specific option to when using an SSL connection. 
    * 
    * @access public 
    * @param string $category category to which the option applies 
    * @param string $option option name 
    * @param string $value  option value 
    * @return void 
    */ 
    function setOpt($category, $option, $value = null) 
    { 
     if (!is_null($value)) { 
      if (!isset($this->__options[$category])) { 
       $this->__options[$category] = array(); 
      } 
      $this->__options[$category][$option] = $value; 
     } else { 
      $this->__options[$category] = $option; 
     } 
    } 

    /** 
    * Overload extension support 
    * if the overload extension is loaded, you can call the client class 
    * with a soap method name 
    * $soap = new SOAP_Client(....); 
    * $value = $soap->getStockQuote('MSFT'); 
    * 
    * @param string method 
    * @param array args 
    * @param string retur_value 
    * 
    * @return boolean 
    * @access public 
    */ 
    function _call($method, $args, &$return_value) 
    { 
     // XXX overloading lowercases the method name, we 
     // need to look into the wsdl and try to find 
     // the correct method name to get the correct 
     // case for the call. 
     if ($this->_wsdl) { 
      $this->_wsdl->matchMethod($method); 
     } 

     $return_value =& $this->call($method, $args); 
     return true; 
    } 

    function &__getlastrequest() 
    { 
     return $this->__last_request; 
    } 

    function &__getlastresponse() 
    { 
     return $this->__last_response; 
    } 

    function __use($use) 
    { 
     $this->__options['use'] = $use; 
    } 

    function __style($style) 
    { 
     $this->__options['style'] = $style; 
    } 

    function __trace($level) 
    { 
     $this->__options['trace'] = $level; 
    } 

    function &__generate($method, &$params, $namespace = false, $soapAction = false) 
    { 
     $this->fault = null; 
     $this->__options['input']='parse'; 
     $this->__options['result']='parse'; 
     $this->__options['parameters'] = false; 
     if ($params && gettype($params) != 'array') { 
      $params = array($params); 
     } 
     if (gettype($namespace) == 'array') { 
      foreach ($namespace as $optname => $opt) { 
       $this->__options[strtolower($optname)] = $opt; 
      } 
      if (isset($this->__options['namespace'])) { 
       $namespace = $this->__options['namespace']; 
      } else { 
       $namespace = false; 
      } 
     } else { 
      // we'll place soapaction into our array for usage in the transport 
      $this->__options['soapaction'] = $soapAction; 
      $this->__options['namespace'] = $namespace; 
     } 

     if ($this->__endpointType == 'wsdl') { 
      $this->_setSchemaVersion($this->_wsdl->xsd); 
      // get portName 
      if (!$this->_portName) { 
       $this->_portName = $this->_wsdl->getPortName($method); 
      } 
      if (PEAR::isError($this->_portName)) { 
       return $this->_raiseSoapFault($this->_portName); 
      } 

      // get endpoint 
      $this->_endpoint = $this->_wsdl->getEndpoint($this->_portName); 
      if (PEAR::isError($this->_endpoint)) { 
       return $this->_raiseSoapFault($this->_endpoint); 
      } 

      // get operation data 
      $opData = $this->_wsdl->getOperationData($this->_portName, $method); 

      if (PEAR::isError($opData)) { 
       return $this->_raiseSoapFault($opData); 
      } 
      $namespace = $opData['namespace']; 
      $this->__options['style'] = $opData['style']; 
      $this->__options['use'] = $opData['input']['use']; 
      $this->__options['soapaction'] = $opData['soapAction']; 

      // set input params 
      if ($this->__options['input'] == 'parse') { 
       $this->__options['parameters'] = $opData['parameters']; 
       $nparams = array(); 
       if (isset($opData['input']['parts']) && count($opData['input']['parts']) > 0) { 
        $i = 0; 
        reset($params); 
        foreach ($opData['input']['parts'] as $name => $part) { 
         $xmlns = ''; 
         $attrs = array(); 
         // is the name actually a complex type? 
         if (isset($part['element'])) { 
          $xmlns = $this->_wsdl->namespaces[$part['namespace']]; 
          $part = $this->_wsdl->elements[$part['namespace']][$part['type']]; 
          $name = $part['name']; 
         } 
         if (array_key_exists($name, $params) || 
          $this->_wsdl->getDataHandler($name, $part['namespace'])) { 
          $nparams[$name] =& $params[$name]; 
         } else { 
          // we now force an associative array for 
          // parameters if using wsdl. 
          return $this->_raiseSoapFault("The named parameter $name is not in the call parameters."); 
         } 
         if (gettype($nparams[$name]) != 'object' || 
          !is_a($nparams[$name],'soap_value')) { 
          // type is a qname likely, split it apart, and get the type namespace from wsdl 
          $qname = new QName($part['type']); 
          if ($qname->ns) { 
           $type_namespace = $this->_wsdl->namespaces[$qname->ns]; 
          } else if (isset($part['namespace'])) { 
           $type_namespace = $this->_wsdl->namespaces[$part['namespace']]; 
          } else { 
           $type_namespace = null; 
          } 
          $qname->namespace = $type_namespace; 
          $type = $qname->name; 
          $pqname = $name; 
          if ($xmlns) { 
           $pqname = '{' . $xmlns . '}' . $name; 
          } 
          $nparams[$name] = new SOAP_Value($pqname, $qname->fqn(), $nparams[$name], $attrs); 
         } else { 
          // wsdl fixups to the soap value. 
         } 
        } 
       } 
       $params =& $nparams; 
       unset($nparams); 
      } 
     } else { 
      $this->_setSchemaVersion(SOAP_XML_SCHEMA_VERSION); 
     } 

     // serialize the message. 
     $this->_section5 = (isset($this->__options['use']) && $this->__options['use'] == 'literal'); 

     if (!isset($this->__options['style']) || $this->__options['style'] == 'rpc') { 
      $this->__options['style'] = 'rpc'; 
      $this->docparams = true; 
      $mqname = new QName($method, $namespace); 
      $methodValue = new SOAP_Value($mqname->fqn(), 'Struct', $params); 
      $soap_msg =& $this->_makeEnvelope($methodValue, $this->headersOut, $this->_encoding, $this->__options); 
     } else { 
      if (!$params) { 
       $mqname = new QName($method, $namespace); 
       $mynull = null; 
       $params = new SOAP_Value($mqname->fqn(), 'Struct', $mynull); 
      } elseif ($this->__options['input'] == 'parse') { 
       if (is_array($params)) { 
        $nparams = array(); 
        $keys = array_keys($params); 
        foreach ($keys as $k) { 
         if (gettype($params[$k]) != 'object') { 
          $nparams[] = new SOAP_Value($k, false, $params[$k]); 
         } else { 
          $nparams[] =& $params[$k]; 
         } 
        } 
        $params =& $nparams; 
       } 
       if ($this->__options['parameters']) { 
        $mqname = new QName($method, $namespace); 
        $params = new SOAP_Value($mqname->fqn(), 'Struct', $params); 
       } 
      } 
      $soap_msg =& $this->_makeEnvelope($params, $this->headersOut, $this->_encoding, $this->__options); 
     } 
     unset($this->headersOut); 

     if (PEAR::isError($soap_msg)) { 
      return $this->_raiseSoapFault($soap_msg); 
     } 

     // handle Mime or DIME encoding 
     // XXX DIME Encoding should move to the transport, do it here for now 
     // and for ease of getting it done 
     if (count($this->__attachments)) { 
      if ((isset($this->__options['attachments']) && $this->__options['attachments'] == 'Mime') || isset($this->__options['Mime'])) { 
       $soap_msg =& $this->_makeMimeMessage($soap_msg, $this->_encoding); 
      } else { 
       // default is dime 
       $soap_msg =& $this->_makeDIMEMessage($soap_msg, $this->_encoding); 
       $this->__options['headers']['Content-Type'] = 'application/dime'; 
      } 
      if (PEAR::isError($soap_msg)) { 
       return $this->_raiseSoapFault($soap_msg); 
      } 
     } 

     // instantiate client 
     if (is_array($soap_msg)) { 
      $soap_data =& $soap_msg['body']; 
      if (count($soap_msg['headers'])) { 
       if (isset($this->__options['headers'])) { 
        $this->__options['headers'] = array_merge($this->__options['headers'], $soap_msg['headers']); 
       } else { 
        $this->__options['headers'] = $soap_msg['headers']; 
       } 
      } 
     } else { 
      $soap_data =& $soap_msg; 
     } 
     return $soap_data; 
    } 

    function &__parse(&$response, $encoding, &$attachments) 
    { 
     // parse the response 
     $response = new SOAP_Parser($response, $encoding, $attachments); 
     if ($response->fault) { 
      return $this->_raiseSoapFault($response->fault); 
     } 
     // return array of parameters 
     $return =& $response->getResponse(); 
     $headers =& $response->getHeaders(); 
     if ($headers) { 
      $this->headersIn =& $this->__decodeResponse($headers, false); 
     } 
     return $this->__decodeResponse($return); 
    } 

    function &__decodeResponse(&$response, $shift = true) 
    { 
     if (!$response) { 
      return null; 
     } 
     // Check for valid response. 
     if (PEAR::isError($response)) { 
      return $this->_raiseSoapFault($response); 
     } elseif (!is_a($response, 'soap_value')) { 
      return $this->_raiseSoapFault("didn't get SOAP_Value object back from client"); 
     } 

     // Decode to native php datatype. 
     $returnArray =& $this->_decode($response); 

     // Fault? 
     if (PEAR::isError($returnArray)) { 
      return $this->_raiseSoapFault($returnArray); 
     } 
     if (is_object($returnArray) && strcasecmp(get_class($returnArray),'stdClass') == 0) { 
      $returnArray = get_object_vars($returnArray); 
     } 
     if (is_array($returnArray)) { 
      if (isset($returnArray['faultcode']) || isset($returnArray['SOAP-ENV:faultcode'])) { 
       $faultcode = $faultstring = $faultdetail = $faultactor = ''; 
       foreach ($returnArray as $k => $v) { 
        if (stristr($k, 'faultcode')) $faultcode = $v; 
        if (stristr($k, 'faultstring')) $faultstring = $v; 
        if (stristr($k, 'detail')) $faultdetail = $v; 
        if (stristr($k, 'faultactor')) $faultactor = $v; 
       } 
       return $this->_raiseSoapFault($faultstring, $faultdetail, $faultactor, $faultcode); 
      } 
      // Return array of return values. 
      if ($shift && count($returnArray) == 1) { 
       return array_shift($returnArray); 
      } 
      return $returnArray; 
     } 
     return $returnArray; 
    } 

    function __get_wire() 
    { 
     if ($this->__options['trace'] > 0 && ($this->__last_request || $this->__last_response)) { 
      return "OUTGOING:\n\n". 
      $this->__last_request. 
      "\n\nINCOMING\n\n". 
      preg_replace("/></",">\r\n<", $this->__last_response); 
     } 
     return null; 
    } 

} 

編輯

我已經輸入...paypal$ grep -R 'Client.php' *,並且我得到這樣的:

PayPal/CallerServices.php://require_once 'PayPal/SOAP/Client.php'; 
PayPal/SOAP/Client.php:// $Id: Client.php,v 1.1.1.1 2006/02/19 
PayPal/SOAP/WSDL.php: //require_once 'PayPal/SOAP/Client.php 

這是肯定的,有我的應用程序沒有更多的文件,其中可能包括客戶端.PHP。

哈維

問候

哈維

+2

double include? – Eineki 2011-05-20 15:09:59

+0

文件是否被include()'兩次?要麼非常小心地包含()它只有一次,或切換到'include_once()'。 – 2011-05-20 15:10:43

+0

你真的在改變班級名稱還是隻是文件名? – AllisonC 2011-05-20 15:12:16

回答

7

我覺得跟類文件被包含兩次,這就是爲什麼它總是就算你改名字的重新聲明。查找重複包含或始終使用require_once()而不是require()

運行這個命令來查找的地方,其中包括文件:

grep -R 'Client.php' * 

另一種方法來調試,是temporaterly這種替換Client.php的所有內容:

<pre> 
<?php 
    print_r(debug_backtrace()); 
?> 
</pre> 
<hr /> 

它會向您展示文件來自何處。

+0

我遵循了你的建議,並且編輯了我的問題。 – ziiweb 2011-05-20 15:43:52

+0

@ user248959我們也編輯了我的答案:) – 2011-05-21 16:10:37