芝麻web文件管理V1.00
编辑当前文件:/home/mgatv524/public_html/mctv/vendor/php-di/php-di/src/Compiler/ObjectCreationCompiler.php
*/ class ObjectCreationCompiler { /** * @var Compiler */ private $compiler; public function __construct(Compiler $compiler) { $this->compiler = $compiler; } public function compile(ObjectDefinition $definition) : string { $this->assertClassIsNotAnonymous($definition); $this->assertClassIsInstantiable($definition); // Lazy? if ($definition->isLazy()) { return $this->compileLazyDefinition($definition); } try { $classReflection = new ReflectionClass($definition->getClassName()); $constructorArguments = $this->resolveParameters($definition->getConstructorInjection(), $classReflection->getConstructor()); $dumpedConstructorArguments = array_map(function ($value) { return $this->compiler->compileValue($value); }, $constructorArguments); $code = []; $code[] = sprintf( '$object = new %s(%s);', $definition->getClassName(), implode(', ', $dumpedConstructorArguments) ); // Property injections foreach ($definition->getPropertyInjections() as $propertyInjection) { $value = $propertyInjection->getValue(); $value = $this->compiler->compileValue($value); $className = $propertyInjection->getClassName() ?: $definition->getClassName(); $property = new ReflectionProperty($className, $propertyInjection->getPropertyName()); if ($property->isPublic()) { $code[] = sprintf('$object->%s = %s;', $propertyInjection->getPropertyName(), $value); } else { // Private/protected property $code[] = sprintf( '\DI\Definition\Resolver\ObjectCreator::setPrivatePropertyValue(%s, $object, \'%s\', %s);', var_export($propertyInjection->getClassName(), true), $propertyInjection->getPropertyName(), $value ); } } // Method injections foreach ($definition->getMethodInjections() as $methodInjection) { $methodReflection = new \ReflectionMethod($definition->getClassName(), $methodInjection->getMethodName()); $parameters = $this->resolveParameters($methodInjection, $methodReflection); $dumpedParameters = array_map(function ($value) { return $this->compiler->compileValue($value); }, $parameters); $code[] = sprintf( '$object->%s(%s);', $methodInjection->getMethodName(), implode(', ', $dumpedParameters) ); } } catch (InvalidDefinition $e) { throw InvalidDefinition::create($definition, sprintf( 'Entry "%s" cannot be compiled: %s', $definition->getName(), $e->getMessage() )); } return implode("\n ", $code); } public function resolveParameters(MethodInjection $definition = null, ReflectionMethod $method = null) : array { $args = []; if (! $method) { return $args; } $definitionParameters = $definition ? $definition->getParameters() : []; foreach ($method->getParameters() as $index => $parameter) { if (array_key_exists($index, $definitionParameters)) { // Look in the definition $value = &$definitionParameters[$index]; } elseif ($parameter->isOptional()) { // If the parameter is optional and wasn't specified, we take its default value $args[] = $this->getParameterDefaultValue($parameter, $method); continue; } else { throw new InvalidDefinition(sprintf( 'Parameter $%s of %s has no value defined or guessable', $parameter->getName(), $this->getFunctionName($method) )); } $args[] = &$value; } return $args; } private function compileLazyDefinition(ObjectDefinition $definition) : string { $subDefinition = clone $definition; $subDefinition->setLazy(false); $subDefinition = $this->compiler->compileValue($subDefinition); $this->compiler->getProxyFactory()->generateProxyClass($definition->getClassName()); return <<
proxyFactory->createProxy( '{$definition->getClassName()}', function (&\$wrappedObject, \$proxy, \$method, \$params, &\$initializer) { \$wrappedObject = $subDefinition; \$initializer = null; // turning off further lazy initialization return true; } ); PHP; } /** * Returns the default value of a function parameter. * * @throws InvalidDefinition Can't get default values from PHP internal classes and functions * @return mixed */ private function getParameterDefaultValue(ReflectionParameter $parameter, ReflectionMethod $function) { try { return $parameter->getDefaultValue(); } catch (\ReflectionException $e) { throw new InvalidDefinition(sprintf( 'The parameter "%s" of %s has no type defined or guessable. It has a default value, ' . 'but the default value can\'t be read through Reflection because it is a PHP internal class.', $parameter->getName(), $this->getFunctionName($function) )); } } private function getFunctionName(ReflectionMethod $method) : string { return $method->getName() . '()'; } private function assertClassIsNotAnonymous(ObjectDefinition $definition) { if (strpos($definition->getClassName(), '@') !== false) { throw InvalidDefinition::create($definition, sprintf( 'Entry "%s" cannot be compiled: anonymous classes cannot be compiled', $definition->getName() )); } } private function assertClassIsInstantiable(ObjectDefinition $definition) { if ($definition->isInstantiable()) { return; } $message = ! $definition->classExists() ? 'Entry "%s" cannot be compiled: the class doesn\'t exist' : 'Entry "%s" cannot be compiled: the class is not instantiable'; throw InvalidDefinition::create($definition, sprintf($message, $definition->getName())); } }