private static function CastValueTo($mixItem, $strNewType) { $strOriginalType = gettype($mixItem); switch (QType::TypeFromDoc($strNewType)) { case QType::Boolean: if ($strOriginalType == QType::Boolean) { return $mixItem; } if (is_null($mixItem)) { return false; } if (strlen($mixItem) == 0) { return false; } if (strtolower($mixItem) == 'false') { return false; } settype($mixItem, $strNewType); return $mixItem; case QType::Integer: if ($strOriginalType == QType::Boolean) { throw new QInvalidCastException(sprintf('Unable to cast %s value to %s: %s', $strOriginalType, $strNewType, $mixItem)); } if (strlen($mixItem) == 0) { return null; } if ($strOriginalType == QType::Integer) { return $mixItem; } // Check to make sure the value hasn't changed significantly $intItem = $mixItem; settype($intItem, $strNewType); $mixTest = $intItem; settype($mixTest, $strOriginalType); // If the value hasn't changed, it's safe to return the casted value if ((string) $mixTest === (string) $mixItem) { return $intItem; } // if casting changed the value, but we have a valid integer, return with a string cast if (preg_match('/^-?\\d+$/', $mixItem) === 1) { return (string) $mixItem; } // any other scenarios is an invalid cast throw new QInvalidCastException(sprintf('Unable to cast %s value to %s: %s', $strOriginalType, $strNewType, $mixItem)); case QType::Float: if ($strOriginalType == QType::Boolean) { throw new QInvalidCastException(sprintf('Unable to cast %s value to %s: %s', $strOriginalType, $strNewType, $mixItem)); } if (strlen($mixItem) == 0) { return null; } if ($strOriginalType == QType::Float) { return $mixItem; } if (!is_numeric($mixItem)) { throw new QInvalidCastException(sprintf('Invalid float: %s', $mixItem)); } // Check to make sure the value hasn't changed significantly $fltItem = $mixItem; settype($fltItem, $strNewType); $mixTest = $fltItem; settype($mixTest, $strOriginalType); //account for any scientific notation that results //find out what notation is currently being used $i = strpos($mixItem, '.'); $precision = $i === false ? 0 : strlen($mixItem) - $i - 1; //and represent the casted value the same way $strTest = sprintf('%.' . $precision . 'f', $fltItem); // If the value hasn't changed, it's safe to return the casted value if ((string) $strTest === (string) $mixItem) { return $fltItem; } // the changed value could be the result of loosing precision. Return the original value with no cast return $mixItem; case QType::String: if ($strOriginalType == QType::String) { return $mixItem; } // Check to make sure the value hasn't changed significantly $strItem = $mixItem; settype($strItem, $strNewType); $mixTest = $strItem; settype($mixTest, $strOriginalType); // Has it? $blnSame = true; if ($strOriginalType == QType::Float) { // type conversion from float to string affects precision and can throw off the comparison // so we need to use a comparison check using an epsilon value instead $epsilon = 1.0E-14; $diff = abs($mixItem - $mixTest); if ($diff > $epsilon) { $blnSame = false; } } else { if ($mixTest != $mixItem) { $blnSame = false; } } if (!$blnSame) { //This is an invalid cast throw new QInvalidCastException(sprintf('Unable to cast %s value to %s: %s', $strOriginalType, $strNewType, $mixItem)); } return $strItem; default: throw new QInvalidCastException(sprintf('Unable to cast %s value to unknown type %s', $strOriginalType, $strNewType)); } }
protected function SetupSoapMethods(ReflectionClass $objReflection) { $objReflectionMethods = $objReflection->getMethods(); if ($objReflectionMethods) { foreach ($objReflectionMethods as $objReflectionMethod) { if ($objReflectionMethod->isPublic() && !$objReflectionMethod->isAbstract() && !$objReflectionMethod->isStatic() && !$objReflectionMethod->isConstructor() && !$objReflectionMethod->isDestructor() && $objReflectionMethod->getDeclaringClass()->getName() != 'QBaseClass') { $objMethod = new QSoapMethod($objReflectionMethod->getName()); $strComments = $objReflectionMethod->getDocComment(); if ($strComments) { // Use Comments to Calculate strType and blnArray $strTypeArray = array(); $blnArrayArray = array(); $strCommentArray = explode("\n", $strComments); foreach ($strCommentArray as $strCommentLine) { $strCommentLine = trim($strCommentLine); $strMatches = array(); preg_match_all("/[\\s]*\\*[\\s]*@param[\\s]+([a-zA-Z0-9_]+)(\\[\\])?[\\s]+[&\$]*([a-zA-Z0-9_]+)/", $strCommentLine, $strMatches); if (count($strMatches) == 4 && count($strMatches[0]) == 1 && count($strMatches[1]) == 1 && count($strMatches[2]) == 1 && count($strMatches[3]) == 1) { $strType = $strMatches[1][0]; $strArray = $strMatches[2][0]; $strName = $strMatches[3][0]; $strTypeArray[$strName] = $strType; if ($strArray == '[]') { $blnArrayArray[$strName] = true; } else { $blnArrayArray[$strName] = false; } } else { $strMatches = array(); preg_match_all("/[\\s]*\\*[\\s]*@return[\\s]+([a-zA-Z0-9_]+)(\\[\\])?/", $strCommentLine, $strMatches); if (count($strMatches) == 3 && count($strMatches[0]) == 1 && count($strMatches[1]) == 1 && count($strMatches[2]) == 1) { $strType = $strMatches[1][0]; $strArray = $strMatches[2][0]; if ($strArray == '[]') { $blnArray = true; } else { $blnArray = false; } try { $strType = QType::TypeFromDoc($strType); } catch (QCallerException $objExc) { $objExc->IncrementOffset(); throw $objExc; } if ($strType != 'void') { $objMethod->ReturnParameter = new QSoapParameter($objMethod->Name . 'Result', $strType, $blnArray, false); } } } } $objParameters = $objReflectionMethod->getParameters(); if ($objParameters) { foreach ($objParameters as $objParameter) { $blnArray = false; $strName = $objParameter->getName(); if (array_key_exists($strName, $strTypeArray)) { try { $strType = QType::TypeFromDoc($strTypeArray[$strName]); } catch (QCallerException $objExc) { $objExc->IncrementOffset(); throw $objExc; } } else { throw new QCallerException('Unable to determine Parameter Type for Method from PHPDoc Comment: ' . $objReflectionMethod->getName() . '(' . $strName . ')'); } if (array_key_exists($strName, $blnArrayArray)) { $blnArray = $blnArrayArray[$strName]; } $objMethod->AddParameter(new QSoapParameter($strName, $strType, $blnArray, $objParameter->isPassedByReference())); } } array_push($this->objMethodArray, $objMethod); } } } } }
private static function CastValueTo($mixItem, $strType) { $strItemType = gettype($mixItem); switch (QType::TypeFromDoc($strType)) { case QType::Boolean: if ($strItemType == QType::Boolean) { return $mixItem; } if (is_null($mixItem)) { return false; } if (strlen($mixItem) == 0) { return false; } if (strtolower($mixItem) == 'false') { return false; } settype($mixItem, $strType); return $mixItem; case QType::Integer: if (strlen($mixItem) == 0) { return null; } if ($mixItem !== true && ((string) (int) $mixItem === (string) $mixItem || preg_match('/^-?\\d+$/', $mixItem) === 1)) { return $mixItem; } else { throw new QInvalidCastException(sprintf('Invalid integer: %s', $mixItem)); } case QType::Float: if (strlen($mixItem) == 0) { return null; } if (!is_numeric($mixItem)) { throw new QInvalidCastException(sprintf('Invalid float: %s', $mixItem)); } return $mixItem; case QType::String: $mixOriginal = $mixItem; settype($mixItem, $strType); // Check to make sure the value hasn't changed significantly $mixTest = $mixItem; settype($mixTest, gettype($mixOriginal)); // Has it? if ($mixTest != $mixOriginal) { // Yes -- therefore this is an invalid cast throw new QInvalidCastException(sprintf('Unable to cast %s value to %s: %s', $strItemType, $strType, $mixOriginal)); } return $mixItem; default: throw new QInvalidCastException(sprintf('Unable to cast %s value to unknown type %s', $strItemType, $strType)); } }