base.php
来自「PHP 知识管理系统(基于树结构的知识管理系统), 英文原版的PHP源码。」· PHP 代码 · 共 1,251 行 · 第 1/3 页
PHP
1,251 行
if (isset($this->_namespaces[$ns])) {
return $this->_namespaces[$ns];
}
$prefix = 'ns' . count($this->_namespaces);
$this->_namespaces[$ns] = $prefix;
return $prefix;
}
function _getNamespaceForPrefix($prefix)
{
$flipped = array_flip($this->_namespaces);
if (isset($flipped[$prefix])) {
return $flipped[$prefix];
}
return null;
}
function _isSoapValue(&$value)
{
return is_a($value, 'SOAP_Value');
}
function _serializeValue(&$value, $name = '', $type = false,
$elNamespace = null, $typeNamespace = null,
$options = array(), $attributes = array(),
$artype = '')
{
$namespaces = array();
$arrayType = $array_depth = $xmlout_value = null;
$typePrefix = $elPrefix = $xmlout_offset = $xmlout_arrayType = '';
$xmlout_type = $xmlns = $ptype = $array_type_ns = '';
if (!$name || is_numeric($name)) {
$name = 'item';
}
if ($this->_wsdl) {
list($ptype, $arrayType, $array_type_ns, $array_depth)
= $this->_wsdl->getSchemaType($type, $name, $typeNamespace);
}
if (!$arrayType) {
$arrayType = $artype;
}
if (!$ptype) {
$ptype = $this->_getType($value);
}
if (!$type) {
$type = $ptype;
}
if (strcasecmp($ptype, 'Struct') == 0 ||
strcasecmp($type, 'Struct') == 0) {
// Struct
$vars = null;
if (is_object($value)) {
$vars = get_object_vars($value);
} else {
$vars = &$value;
}
if (is_array($vars)) {
foreach (array_keys($vars) as $k) {
// Hide private vars.
if ($k[0] == '_') continue;
if (is_object($vars[$k])) {
if (is_a($vars[$k], 'SOAP_Value')) {
$xmlout_value .= $vars[$k]->serialize($this);
} else {
// XXX get the members and serialize them instead
// converting to an array is more overhead than we
// should really do.
$xmlout_value .= $this->_serializeValue(get_object_vars($vars[$k]), $k, false, $this->_section5 ? null : $elNamespace);
}
} else {
if ($this->isValidField($k, $type))
{
$xmlout_value .= $this->_serializeValue($vars[$k], $k, false, $this->_section5 ? null : $elNamespace);
}
}
}
}
} elseif (strcasecmp($ptype, 'Array') == 0 ||
strcasecmp($type, 'Array') == 0) {
// Array.
$typeNamespace = SOAP_SCHEMA_ENCODING;
$orig_type = $type;
$type = 'Array';
$numtypes = 0;
// XXX this will be slow on larger arrays. Basically, it flattens
// arrays to allow us to serialize multi-dimensional arrays. We
// only do this if arrayType is set, which will typically only
// happen if we are using WSDL
if (isset($options['flatten']) ||
($arrayType &&
(strchr($arrayType, ',') || strstr($arrayType, '][')))) {
$numtypes = $this->_multiArrayType($value, $arrayType,
$ar_size, $xmlout_value);
}
$array_type = $array_type_prefix = '';
if ($numtypes != 1) {
$arrayTypeQName =& new QName($arrayType);
$arrayType = $arrayTypeQName->name;
$array_types = array();
$array_val = null;
// Serialize each array element.
$ar_size = count($value);
foreach ($value as $array_val) {
if ($this->_isSoapValue($array_val)) {
$array_type = $array_val->type;
$array_types[$array_type] = 1;
$array_type_ns = $array_val->type_namespace;
$xmlout_value .= $array_val->serialize($this);
} else {
$array_type = $this->_getType($array_val);
$array_types[$array_type] = 1;
$xmlout_value .= $this->_serializeValue($array_val, 'item', $array_type, $this->_section5 ? null : $elNamespace);
}
}
$xmlout_offset = ' SOAP-ENC:offset="[0]"';
if (!$arrayType) {
/*
$numtypes = count($array_types);
if ($numtypes == 1) {
$arrayType = $array_type;
}
*/
// Using anyType is more interoperable.
if ($array_type == 'Struct') {
$array_type = '';
} elseif ($array_type == 'Array') {
$arrayType = 'anyType';
$array_type_prefix = 'xsd';
} else {
if (!$arrayType) {
$arrayType = $array_type;
}
}
}
}
if (!$arrayType || $numtypes > 1) {
// Should reference what schema we're using.
$arrayType = 'xsd:anyType';
} else {
if ($array_type_ns) {
$array_type_prefix = $this->_getNamespacePrefix($array_type_ns);
} elseif (isset($this->_typemap[$this->_XMLSchemaVersion][$arrayType])) {
$array_type_prefix = $this->_namespaces[$this->_XMLSchemaVersion];
}
if ($array_type_prefix) {
$arrayType = $array_type_prefix . ':' . $arrayType;
}
}
$xmlout_arrayType = ' SOAP-ENC:arrayType="' . $arrayType;
if ($array_depth != null) {
for ($i = 0; $i < $array_depth; $i++) {
$xmlout_arrayType .= '[]';
}
}
$xmlout_arrayType .= "[$ar_size]\"";
} elseif ($this->_isSoapValue($value)) {
$xmlout_value = $value->serialize($this);
} elseif ($type == 'string') {
$xmlout_value = htmlspecialchars($value);
} elseif ($type == 'rawstring') {
$xmlout_value =& $value;
} elseif ($type == 'boolean') {
$xmlout_value = $value ? 'true' : 'false';
} else {
$xmlout_value =& $value;
}
// Add namespaces.
if ($elNamespace) {
$elPrefix = $this->_getNamespacePrefix($elNamespace);
if ($elPrefix) {
$xmlout_name = "$elPrefix:$name";
} else {
$xmlout_name = $name;
}
} else {
$xmlout_name = $name;
}
if ($typeNamespace) {
$typePrefix = $this->_getNamespacePrefix($typeNamespace);
if ($typePrefix) {
$xmlout_type = "$typePrefix:$type";
} else {
$xmlout_type = $type;
}
} elseif ($type &&
isset($this->_typemap[$this->_XMLSchemaVersion][$type])) {
$typePrefix = $this->_namespaces[$this->_XMLSchemaVersion];
if ($typePrefix) {
$xmlout_type = "$typePrefix:$type";
} else {
$xmlout_type = $type;
}
}
// Handle additional attributes.
$xml_attr = '';
if (count($attributes)) {
foreach ($attributes as $k => $v) {
$kqn =& new QName($k);
$vqn =& new QName($v);
$xml_attr .= ' ' . $kqn->fqn() . '="' . $vqn->fqn() . '"';
}
}
// Store the attachment for mime encoding.
if (isset($options['attachment']) &&
!PEAR::isError($options['attachment'])) {
$this->__attachments[] = $options['attachment'];
}
if ($this->_section5) {
if ($xmlout_type) {
$xmlout_type = " xsi:type=\"$xmlout_type\"";
}
if (is_null($xmlout_value)) {
$xml = "\r\n<$xmlout_name$xmlout_type$xmlns$xmlout_arrayType" .
"$xml_attr xsi:nil=\"true\"/>";
} else {
$xml = "\r\n<$xmlout_name$xmlout_type$xmlns$xmlout_arrayType" .
"$xmlout_offset$xml_attr>$xmlout_value</$xmlout_name>";
}
} else {
if (is_null($xmlout_value)) {
$xml = "\r\n<$xmlout_name$xmlns$xml_attr/>";
} else {
$xml = "\r\n<$xmlout_name$xmlns$xml_attr>" .
$xmlout_value . "</$xmlout_name>";
}
}
return $xml;
}
/**
* Converts a PHP type to a SOAP type.
*
* @access private
*
* @param string $value The value to inspect.
*
* @return string The value's SOAP type.
*/
function _getType(&$value)
{
global $SOAP_OBJECT_STRUCT, $SOAP_RAW_CONVERT;
$type = gettype($value);
switch ($type) {
case 'object':
if (is_a($value, 'soap_value')) {
$type = $value->type;
} else {
$type = 'Struct';
}
break;
case 'array':
// Hashes are always handled as structs.
if ($this->_isHash($value)) {
$type = 'Struct';
} else {
$ar_size = count($value);
reset($value);
$key1 = key($value);
if ($ar_size > 0 && is_a($key1, 'SOAP_Value')) {
// FIXME: for non-wsdl structs that are all the same type
$key2 = key($value);
if ($ar_size > 1 &&
$this->_isSoapValue($key1) &&
$this->_isSoapValue($key2) &&
$key1->name != $key2->name) {
// This is a struct, not an array.
$type = 'Struct';
} else {
$type = 'Array';
}
} else {
$type = 'Array';
}
}
break;
case 'integer':
case 'long':
$type = 'int';
break;
case 'boolean':
break;
case 'double':
// double is deprecated in PHP 4.2 and later.
$type = 'float';
break;
case 'null':
$type = '';
break;
case 'string':
if ($SOAP_RAW_CONVERT) {
if (is_numeric($value)) {
if (strstr($value, '.')) {
$type = 'float';
} else {
$type = 'int';
}
} else {
if (SOAP_Type_hexBinary::is_hexbin($value)) {
$type = 'hexBinary';
} else {
if ($this->_isBase64($value)) {
$type = 'base64Binary';
} else {
$dt =& new SOAP_Type_dateTime($value);
if ($dt->toUnixtime() != -1) {
$type = 'dateTime';
}
}
}
}
}
break;
default:
break;
}
return $type;
}
function _multiArrayType(&$value, &$type, &$size, &$xml)
{
$sz = count($value);
if (is_array($value)) {
// Seems we have a multi dimensional array, figure it out if we
// do.
$c = count($value);
for ($i = 0; $i < $c; $i++) {
$this->_multiArrayType($value[$i], $type, $size, $xml);
}
if ($size) {
$size = $sz. ',' . $size;
} else {
$size = $sz;
}
return 1;
} else {
if (is_object($value)) {
$type = $value->type;
$xml .= $value->serialize($this);
} else {
$type = $this->_getType($value);
$xml .= $this->_serializeValue($value, 'item', $type);
}
}
$size = null;
return 1;
}
/**
* Returns whether a string is base64 encoded data.
*
* @param string $value The string to check.
*
* @return boolean True if the specified value seems to be base64 encoded.
*/
function _isBase64(&$value)
{
$l = strlen($value);
if ($l) {
return $value[$l - 1] == '=' &&
preg_match('/[A-Za-z=\/\+]+/', $value);
}
return false;
}
/**
* Returns whether a type is a base64 type.
*
* @param string $type A type name.
*
* @return boolean True if the type name is a base64 type.
*/
function _isBase64Type($type)
{
return $type == 'base64' || $type == 'base64Binary';
}
/**
* Returns whether an array is a hash.
*
* @param array $a An array to check.
*
* @return boolean True if the specified array is a hash.
*/
function _isHash(&$a)
{
// I really dislike having to loop through this in PHP code, really
// large arrays will be slow. We need a C function to do this.
$names = array();
$it = 0;
foreach ($a as $k => $v) {
// Checking the type is faster than regexp.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?