views:

165

answers:

3

hey all i want to use ReflectionClass to load some classes defined in my xml file

but i am getting an error

Error while register class :Class ReportErrorHandler does not exist

i will not get this error when i will use

require_once( 'handlers/system/ReportErrorHandler.php' );

but i dont want to require_once the class ,this is why i am using reflection and in my xml file i am writing only the class name with no full path ,so i cant dynamically 'require_once'

here is my code

 public function init(){
$doc = new DOMDocument();
$doc->load( 'server.xml' );

$handlers = $doc->getElementsByTagName( "handler" );
foreach( $handlers as $handler ) {
  $this->register($handler->nodeValue);
}
}

public function register(&$name) {
try{
  $intercafe = new ReflectionClass('Handler');

  $reflectionClass = new ReflectionClass($name);

  if(!$reflectionClass->isSubclassOf($intercafe)){
    //LOG ERROR
    error_log("Init-> Error ," + name + " is not a subclass of [net/Handler]");

    throw new InvalidArgumentException();
  }

  error_log("register: " . $reflectionClass);

  $handler  = $reflectionClass->newInstance();
  $type = $handler->getType();

  //LOG DEBUG
  syslog(LOG_DEBUG ,"Registering handler = " . $name . " TYPE = " . $type);

  $key = $type << 32;

  $this->table[$key] = $reflectionClass;
}catch(Exception $ee){
  error_log("Error while register class :" . $ee->getMessage());
}
}

my xml file

<?xml version="1.0" encoding="UTF-8"?>
  <server>
     <server-version>0.1</server-version>

     <handlers>
       <handler>AuthenticateHandler</handler>
       <handler>ReportErrorHandler</handler>

       <handler>DisconnectedHandler</handler>
       <handler>NoSuchRequestHandler</handler>
     </handlers>
  </server>
+2  A: 

Setup Autoloading with

Gordon
this is what i get , Error while register class :Function 'ReportErrorHandler' not found (function 'ReportErrorHandler' not found or invalid function name)
shay
@shay Like @Mark already said, you have to include the files. The autoloader can do this for you automatically, so you dont have to write include statements, but you have to set it up so it can find your classes. It doesnt matter how it is done in Java. PHP aint Java.
Gordon
+3  A: 

but i dont want to require_once the class ,this is why i am using reflection

Even reflection needs to know what it is that it's supposed to be reflecting. Why don't you want to include/require the class definition?

Mark Baker
cause , in my xml there is only a class file to load ,and i was thinking to my self that this is weird to put the full path in the xml , and use reflection with the parsed class name only and requirre_once with the full path , i mean in java i don't need to import the class to reflect its just a class ,its not an instance
shay
this is what i have to do . use full path for require_once and use className for reflection ?
shay
That's where setting up an autoloader (as Gordon has indicated) will automatically include/require the class file for you... but even an autoloader still needs to know where to look to find the file if it isn't in the include path
Mark Baker
autoload directory , what happens when i have many classes in different directories?
shay
@shay Typically, most people use a naming convention for their classes that allows them to resolve a directory path from the class name.... e.g. class PHPExcel_Worksheet_Row resolves to PHPExcel/Worksheet/Row.php
Mark Baker
A: 

this is what is did to solve my problem i separate the full path for require_once

public function register(&$name) {
try{
  $intercafe = new ReflectionClass('Handler');

  $fullPath = $name;
  $className = $name;

  $index = strrpos($name , "/");
  if($index != False){
    $className = substr($name ,$index + 1);
  }

  $requirePath = 'handlers/' . $fullPath . '.php';
  require_once ( $requirePath );
  $reflectionClass = new ReflectionClass($className);

  if(!$reflectionClass->isSubclassOf($intercafe)){
    //LOG ERROR
    error_log("Init-> Error ," + name + " is not a subclass of [net/Handler]");

    throw new InvalidArgumentException();
  }

  $handler  = $reflectionClass->newInstance();
  $type = $handler->getType();

  //LOG DEBUG
  syslog(LOG_DEBUG ,"Registering handler = " . $name . " TYPE = " . $type);

  $key = $type << 32;

  $this->table[$key] = $reflectionClass;
}catch(Exception $ee){
  error_log("Error while register class :" . $ee->getMessage());
}

}

shay