← Назад к вопросам
Приведи пример использования рефлексии в бизнес-логике
2.0 Middle🔥 121 комментариев
#PHP Core
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Reflection u PHP - Prakticki primjeri
Reflection (Refleksija) je mehanizam koji omogucava inspektovanje klasa, metoda, svojstava i parametara tokom izvrsavanja programa. Veoma je mocan u rjesavanju realnih problema.
Primjer 1: Serializer/Deserializer
class JsonSerializer {
public function serialize(object $obj): string {
$reflection = new ReflectionClass($obj);
$data = [];
foreach ($reflection->getProperties(ReflectionProperty::IS_PUBLIC) as $prop) {
$data[$prop->getName()] = $prop->getValue($obj);
}
return json_encode($data);
}
public function deserialize(string $json, string $className): object {
$data = json_decode($json, true);
$reflection = new ReflectionClass($className);
$obj = $reflection->newInstanceWithoutConstructor();
foreach ($data as $key => $value) {
$prop = $reflection->getProperty($key);
$prop->setAccessible(true);
$prop->setValue($obj, $value);
}
return $obj;
}
}
// Upotreba
class User {
public string $name;
public string $email;
}
$user = new User();
$user->name = 'John';
$user->email = 'john@example.com';
$serializer = new JsonSerializer();
$json = $serializer->serialize($user);
echo $json; // {"name":"John","email":"john@example.com"}
$restored = $serializer->deserialize($json, User::class);
echo $restored->name; // John
Primjer 2: ORM - Mapiranje baze na objekte
class ORM {
public function mapResultToObject(array $row, string $className): object {
$reflection = new ReflectionClass($className);
$instance = new $className();
foreach ($reflection->getProperties() as $property) {
$propertyName = $property->getName();
if (isset($row[$propertyName])) {
$property->setAccessible(true);
$type = $property->getType();
$value = $row[$propertyName];
// Kastovanje tipa
if ($type && $type->getName() === 'int') {
$value = (int)$value;
} elseif ($type && $type->getName() === 'float') {
$value = (float)$value;
}
$property->setValue($instance, $value);
}
}
return $instance;
}
}
class Product {
public int $id;
public string $name;
public float $price;
}
$orm = new ORM();
$row = ['id' => 1, 'name' => 'Laptop', 'price' => 999.99];
$product = $orm->mapResultToObject($row, Product::class);
echo $product->price; // 999.99 (float)
Primjer 3: Validator sa Atributima
#[Attribute]
class Required {}
#[Attribute]
class Email {}
#[Attribute]
class MinLength {
public function __construct(public int $length) {}
}
class Validator {
public function validate(object $obj): array {
$errors = [];
$reflection = new ReflectionClass($obj);
foreach ($reflection->getProperties() as $property) {
$value = $property->getValue($obj);
$attributes = $property->getAttributes();
foreach ($attributes as $attr) {
$attrInstance = $attr->newInstance();
if ($attrInstance instanceof Required && empty($value)) {
$errors[] = $property->getName() . ' je obavezno';
}
if ($attrInstance instanceof Email && !filter_var($value, FILTER_VALIDATE_EMAIL)) {
$errors[] = $property->getName() . ' nije validan email';
}
if ($attrInstance instanceof MinLength && strlen($value) < $attrInstance->length) {
$errors[] = $property->getName() . ' mora biti duzi od ' . $attrInstance->length;
}
}
}
return $errors;
}
}
class UserForm {
#[Required]
#[Email]
public string $email;
#[Required]
#[MinLength(8)]
public string $password;
}
$form = new UserForm();
$form->email = 'invalid';
$form->password = '123';
$validator = new Validator();
$errors = $validator->validate($form);
print_r($errors);
// Ispisuje sve greske: email nije validan, password je prekratak
Primjer 4: Dependency Injection Container
class DIContainer {
private array $services = [];
public function register(string $serviceName, string $className): void {
$this->services[$serviceName] = $className;
}
public function get(string $serviceName): object {
$className = $this->services[$serviceName];
$reflection = new ReflectionClass($className);
// Pronalazi konstruktor
$constructor = $reflection->getConstructor();
if ($constructor === null) {
return new $className();
}
// Dobija parametre konstruktora
$params = [];
foreach ($constructor->getParameters() as $param) {
$paramType = $param->getType();
if ($paramType && !$paramType->isBuiltin()) {
// Rekurzivno resava zavisnosti
$depClassName = $paramType->getName();
$params[] = $this->get($depClassName);
}
}
return $reflection->newInstanceArgs($params);
}
}
interface LoggerInterface {}
class Logger implements LoggerInterface {}
class UserService {
public function __construct(private LoggerInterface $logger) {}
}
$container = new DIContainer();
$container->register(LoggerInterface::class, Logger::class);
$container->register(UserService::class, UserService::class);
$userService = $container->get(UserService::class);
// UserService je automatski instanciran sa Logger zavisnoscu
Primjer 5: Docblock Parser
class DocBlockParser {
public function getMethodDocumentation(string $className, string $methodName): ?string {
$reflection = new ReflectionMethod($className, $methodName);
return $reflection->getDocComment();
}
public function getParamDescription(string $className, string $methodName, string $paramName): ?string {
$reflection = new ReflectionMethod($className, $methodName);
$docComment = $reflection->getDocComment();
if (preg_match("/@param\s+\S+\s+\$" . $paramName . "\s+(.+)/", $docComment, $matches)) {
return $matches[1];
}
return null;
}
}
class PaymentService {
/**
* Procesa plaćanje
* @param float $amount Iznos koji se plaća
*/
public function process(float $amount): void {}
}
$parser = new DocBlockParser();
echo $parser->getParamDescription(PaymentService::class, 'process', 'amount');
// Ispisuje: Iznos koji se plaća
Prednosti Refleksije
- Automatizacija - ORM, validatori, serializers
- Fleksibilnost - dinamicko ponasanje bez hardkoda
- Framework mogucnosti - Dependency injection, atributi
- Introspection - Analiza koda tokom izvrsavanja
Nedostaci
- Performanse - Refleksija je spora, cachaj gdje god je moguce
- Type Safety - Runtime problemi, greske tek pri izvrsavanju
- Citljivost - Magicni kod, teze za debugging
Best Practices
// Cachuj reflection objekti
class CachedReflection {
private static array $cache = [];
public static function getClass(string $className): ReflectionClass {
if (!isset(self::$cache[$className])) {
self::$cache[$className] = new ReflectionClass($className);
}
return self::$cache[$className];
}
}
Zakljucak: Reflection je mocan alat za pisanje fleksibilnog i generalnog koda koji se automatski prilagodava razlicitim klasama i strukturama.