base.php

来自「PHP 知识管理系统(基于树结构的知识管理系统), 英文原版的PHP源码。」· PHP 代码 · 共 1,251 行 · 第 1/3 页

PHP
1,251
字号
            $t = gettype($k);
            if ($t != 'integer') {
                return true;
            } elseif ($this->_isSoapValue($v)) {
                $names[$v->name] = 1;
            }
            // If someone has a large hash they should really be defining the
            // type.
            if ($it++ > 10) {
                return false;
            }
        }
        return count($names)>1;
    }

    function _un_htmlentities($string)
    {
        $trans_tbl = get_html_translation_table(HTML_ENTITIES);
        $trans_tbl = array_flip($trans_tbl);
        return strtr($string, $trans_tbl);
    }

    function &_decode(&$soapval)
    {
        global $SOAP_OBJECT_STRUCT;

        if (!$this->_isSoapValue($soapval)) {
            return $soapval;
        } elseif (is_array($soapval->value)) {
            if ($SOAP_OBJECT_STRUCT && $soapval->type != 'Array') {
                $classname = $this->_defaultObjectClassname;
                if (isset($this->_type_translation[$soapval->tqn->fqn()])) {
                    // This will force an error in PHP if the class does not
                    // exist.
                    $classname = $this->_type_translation[$soapval->tqn->fqn()];
                } elseif (isset($this->_type_translation[$soapval->type])) {
                    // This will force an error in PHP if the class does not
                    // exist.
                    $classname = $this->_type_translation[$soapval->type];
                } elseif ($this->_auto_translation) {
                    if (class_exists($soapval->type)) {
                        $classname = $soapval->type;
                    } elseif ($this->_wsdl) {
                        $t = $this->_wsdl->getComplexTypeNameForElement($soapval->name, $soapval->namespace);
                        if ($t && class_exists($t)) {
                            $classname = $t;
                        }
                    }
                }
                $return =& new $classname;
            } else {
                $return = array();
            }

            $counter = 1;
            $isstruct = !$SOAP_OBJECT_STRUCT || !is_array($return);
            foreach ($soapval->value as $item) {
                if (is_object($return)) {
                    if ($this->_wsdl) {
                        // Get this child's WSDL information.
                        // /$soapval->ns/$soapval->type/$item->ns/$item->name
                        $child_type = $this->_wsdl->getComplexTypeChildType(
                            $soapval->namespace,
                            $soapval->name,
                            $item->namespace,
                            $item->name);
                        if ($child_type) {
                            $item->type = $child_type;
                        }
                    }
                    if (!$isstruct || $item->type == 'Array') {
                        if (isset($return->{$item->name}) &&
                            is_object($return->{$item->name})) {
                            $return->{$item->name} =& $this->_decode($item);
                        } elseif (isset($return->{$item->name}) &&
                                  is_array($return->{$item->name})) {
                            $return->{$item->name}[] = $this->_decode($item);
                        } elseif (is_array($return)) {
                            $return[] =& $this->_decode($item);
                        } else {
                            $return->{$item->name} =& $this->_decode($item);
                        }
                    } elseif (isset($return->{$item->name})) {
                        $isstruct = false;
                        if (count(get_object_vars($return)) == 1) {
                            $d =& $this->_decode($item);
                            $return = array($return->{$item->name}, $d);
                        } else {
                            $d =& $this->_decode($item);
                            $return->{$item->name} = array($return->{$item->name}, $d);
                        }
                    } else {
                        $return->{$item->name} =& $this->_decode($item);
                    }
                    // Set the attributes as members in the class.
                    if (method_exists($return, '__set_attribute')) {
                        foreach ($soapval->attributes as $key => $value) {
                            call_user_func_array(array(&$return,
                                                       '__set_attribute'),
                                                 array($key, $value));
                        }
                    }
                } else {
                    if ($soapval->arrayType && $this->_isSoapValue($item)) {
                        if ($this->_isBase64Type($item->type) &&
                            !$this->_isBase64Type($soapval->arrayType)) {
                            // Decode the value if we're losing the base64
                            // type information.
                            $item->value = base64_decode($item->value);
                        }
                        $item->type = $soapval->arrayType;
                    }
                    if (!$isstruct) {
                        $return[] = $this->_decode($item);
                    } elseif (isset($return[$item->name])) {
                        $isstruct = false;
                        $d =& $this->_decode($item);
                        $return = array($return[$item->name], $d);
                    } else {
                        $return[$item->name] = $this->_decode($item);
                    }
                }
            }

            return $return;
        }

        if ($soapval->type == 'boolean') {
            if ($soapval->value != '0' &&
                strcasecmp($soapval->value, 'false') != 0) {
                $soapval->value = true;
            } else {
                $soapval->value = false;
            }
        } elseif ($soapval->type &&
                  isset($this->_typemap[SOAP_XML_SCHEMA_VERSION][$soapval->type])) {
            // If we can, set variable type.
            settype($soapval->value,
                    $this->_typemap[SOAP_XML_SCHEMA_VERSION][$soapval->type]);
        }

        if ($this->_isBase64Type($soapval->type)) {
            return base64_decode($soapval->value);
        } else {
            return $soapval->value;
        }
    }

    /**
     * Creates the SOAP envelope with the SOAP envelop data.
     *
     * @access private
     *
     * @param
     * @param array $headers
     * @param string $encoding
     * @param array $options
     *
     * @return string
     */
    function _makeEnvelope(&$method, &$headers,
                           $encoding = SOAP_DEFAULT_ENCODING,
                           $options = array())
    {
        $smsg = $header_xml = $ns_string = '';

        if ($headers) {
            $c = count($headers);
            for ($i = 0; $i < $c; $i++) {
                $header_xml .= $headers[$i]->serialize($this);
            }
            $header_xml = "<SOAP-ENV:Header>\r\n$header_xml\r\n</SOAP-ENV:Header>\r\n";
        }

        if (!isset($options['input']) || $options['input'] == 'parse') {
            if (is_array($method)) {
                $c = count($method);
                for ($i = 0; $i < $c; $i++) {
                    $smsg .= $method[$i]->serialize($this);
                }
            } else {
                $smsg = $method->serialize($this);
            }
        } else {
            $smsg = $method;
        }
        $body = "<SOAP-ENV:Body>\r\n" . $smsg . "\r\n</SOAP-ENV:Body>\r\n";

        foreach ($this->_namespaces as $k => $v) {
            $ns_string .= " xmlns:$v=\"$k\"\r\n";
        }
        if ($this->_namespace) {
            $ns_string .= " xmlns=\"{$this->_namespace}\"\r\n";
        }

        /* If 'use' == 'literal', we do not put in the encodingStyle.  This is
         * denoted by $this->_section5 being false.  'use' can be defined at a
         * more granular level than we are dealing with here, so this does not
         * work for all services. */
        $xml = "<?xml version=\"1.0\" encoding=\"$encoding\"?>\r\n\r\n".
            "<SOAP-ENV:Envelope $ns_string".
            ($this->_section5 ? ' SOAP-ENV:encodingStyle="' . SOAP_SCHEMA_ENCODING . '"' : '').
            ">\r\n".
            "$header_xml$body</SOAP-ENV:Envelope>\r\n";

        return $xml;
    }

    function _makeMimeMessage(&$xml, $encoding = SOAP_DEFAULT_ENCODING)
    {
        global $SOAP_options;

        if (!isset($SOAP_options['Mime'])) {
            return $this->_raiseSoapFault('Mime is not installed');
        }

        // Encode any attachments.
        // See http://www.w3.org/TR/SOAP-attachments
        // Now we have to mime encode the message.
        $params = array('content_type' => 'multipart/related; type=text/xml');
        $msg =& new Mail_mimePart('', $params);

        // Add the xml part.
        $params['content_type'] = 'text/xml';
        $params['charset'] = $encoding;
        $params['encoding'] = 'base64';
        $msg->addSubPart($xml, $params);

        // Add the attachements
        $c = count($this->__attachments);
        for ($i = 0; $i < $c; $i++) {
            $attachment =& $this->__attachments[$i];
            $msg->addSubPart($attachment['body'], $attachment);
        }

        return $msg->encode();
    }

    // TODO: this needs to be used from the Transport system.
    function _makeDIMEMessage($xml)
    {
        global $SOAP_options;

        if (!isset($SOAP_options['DIME'])) {
            return $this->_raiseSoapFault('DIME is not installed');
        }

        // Encode any attachments.
        // See http://search.ietf.org/internet-drafts/draft-nielsen-dime-soap-00.txt
        // Now we have to DIME encode the message
        $dime =& new Net_DIME_Message();
        $msg = $dime->encodeData($xml, SOAP_ENVELOP, null, NET_DIME_TYPE_URI);

        // Add the attachments.
        $c = count($this->__attachments);
        for ($i = 0; $i < $c; $i++) {
            $attachment =& $this->__attachments[$i];
            $msg .= $dime->encodeData($attachment['body'],
                                      $attachment['content_type'],
                                      $attachment['cid'],
                                      NET_DIME_TYPE_MEDIA);
        }
        $msg .= $dime->endMessage();

        return $msg;
    }

    function _decodeMimeMessage(&$data, &$headers, &$attachments)
    {
        global $SOAP_options;

        if (!isset($SOAP_options['Mime'])) {
            $this->_raiseSoapFault('Mime Unsupported, install PEAR::Mail::Mime', '', '', 'Server');
            return;
        }

        $params['include_bodies'] = true;
        $params['decode_bodies']  = true;
        $params['decode_headers'] = true;

        // Lame thing to have to do for decoding.
        $decoder =& new Mail_mimeDecode($data);
        $structure = $decoder->decode($params);

        if (isset($structure->body)) {
            $data = $structure->body;
            $headers = $structure->headers;

            return;
        } elseif (isset($structure->parts)) {
            $data = $structure->parts[0]->body;
            $headers = array_merge($structure->headers,
                                   $structure->parts[0]->headers);
            if (count($structure->parts) > 1) {
                $mime_parts = array_splice($structure->parts,1);
                // Prepare the parts for the SOAP parser.

                $c = count($mime_parts);
                for ($i = 0; $i < $c; $i++) {
                    $p =& $mime_parts[$i];
                    if (isset($p->headers['content-location'])) {
                        // TODO: modify location per SwA note section 3
                        // http://www.w3.org/TR/SOAP-attachments
                        $attachments[$p->headers['content-location']] = $p->body;
                    } else {
                        $cid = 'cid:' . substr($p->headers['content-id'], 1, -1);
                        $attachments[$cid] = $p->body;
                    }
                }
            }

            return;
        }

        $this->_raiseSoapFault('Mime parsing error', '', '', 'Server');
    }

    function _decodeDIMEMessage(&$data, &$headers, &$attachments)
    {
        global $SOAP_options;

        if (!isset($SOAP_options['DIME'])) {
            $this->_raiseSoapFault('DIME Unsupported, install PEAR::Net::DIME', '', '', 'Server');
            return;
        }

        // This SHOULD be moved to the transport layer, e.g. PHP itself should
        // handle parsing DIME ;)
        $dime =& new Net_DIME_Message();
        $err = $dime->decodeData($data);
        if (PEAR::isError($err)) {
            $this->_raiseSoapFault('Failed to decode the DIME message!', '', '', 'Server');
            return;
        }
        if (strcasecmp($dime->parts[0]['type'], SOAP_ENVELOP) != 0) {
            $this->_raiseSoapFault('DIME record 1 is not a SOAP envelop!', '', '', 'Server');
            return;
        }

        $data = $dime->parts[0]['data'];
        // Fake it for now.
        $headers['content-type'] = 'text/xml';
        $c = count($dime->parts);
        for ($i = 0; $i < $c; $i++) {
            $part =& $dime->parts[$i];
            // We need to handle URI's better.
            $id = strncmp($part['id'], 'cid:', 4)
                ? 'cid:' . $part['id']
                : $part['id'];
            $attachments[$id] = $part['data'];
        }
    }

    function __set_type_translation($type, $class = null)
    {
        $tq =& new QName($type);
        if (!$class) {
            $class = $tq->name;
        }
        $this->_type_translation[$type]=$class;
    }

}

/**
 * Class used to handle QNAME values in XML.
 *
 * @access   public
 * @package  SOAP
 * @author   Shane Caraveo <shane@php.net> Conversion to PEAR and updates
 */
class QName
{
    var $name = '';
    var $ns = '';
    var $namespace='';

    function QName($name, $namespace = '')
    {
        if ($name && $name[0] == '{') {
            preg_match('/\{(.*?)\}(.*)/', $name, $m);
            $this->name = $m[2];
            $this->namespace = $m[1];
        } elseif (substr_count($name, ':') == 1) {
            $s = explode(':', $name);
            $s = array_reverse($s);
            $this->name = $s[0];
            $this->ns = $s[1];
            $this->namespace = $namespace;
        } else {
            $this->name = $name;
            $this->namespace = $namespace;
        }

        // A little more magic than should be in a qname.
        $p = strpos($this->name, '[');
        if ($p) {
            // TODO: Need to re-examine this logic later.
            // Chop off [].
            $this->arraySize = explode(',', substr($this->name, $p + 1, -$p - 2));
            $this->arrayInfo = substr($this->name, $p);
            $this->name = substr($this->name, 0, $p);
        }
    }

    function fqn()
    {
        if ($this->namespace) {
            return '{' . $this->namespace . '}' . $this->name;
        } elseif ($this->ns) {
            return $this->ns . ':' . $this->name;
        }
        return $this->name;
    }

}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?