/** * Attempts to dispatch the supplied Route object. Returns false if it fails * @param Route $route * @throws classFileNotFoundException * @throws badClassNameException * @throws classNameNotFoundException * @throws classMethodNotFoundException * @throws classNotSpecifiedException * @throws methodNotSpecifiedException * @return mixed - result of controller method or FALSE on error */ public function dispatch(Route $route) { $class = trim($route->getMapClass()); $method = trim($route->getMapMethod()); $arguments = $route->getMapArguments(); if ('' === $class) { throw new classNotSpecifiedException('Class Name not specified'); } if ('' === $method) { throw new methodNotSpecifiedException('Method Name not specified'); } //Because the class could have been matched as a dynamic element, // it would mean that the value in $class is untrusted. Therefore, // it may only contain alphanumeric characters. Anything not matching // the regexp is considered potentially harmful. $class = str_replace('\\', '', $class); preg_match('/^[a-zA-Z0-9_]+$/', $class, $matches); if (count($matches) !== 1) { throw new badClassNameException('Disallowed characters in class name ' . $class); } //Apply the suffix $file_name = $this->classPath . $class . $this->suffix; $class = $class . str_replace('.php', '', $this->suffix); //At this point, we are relatively assured that the file name is safe // to check for it's existence and require in. if (FALSE === file_exists($file_name)) { throw new classFileNotFoundException('Class file not found'); } else { require_once $file_name; } //Check for the class class if (FALSE === class_exists($class)) { throw new classNameNotFoundException('class not found ' . $class); } //Check for the method if (FALSE === method_exists($class, $method)) { throw new classMethodNotFoundException('method not found ' . $method); } //All above checks should have confirmed that the class can be instatiated // and the method can be called $obj = new $class(); return call_user_func(array($obj, $method), $arguments); }
public function testExtractingDynamicArguments() { $route = new Route(); $route->setPath('/class/method/:id1/:id2'); $route->addDynamicElement(':id1', ':id1'); $route->addDynamicElement(':id2', ':id2'); $route->matchMap('/class/method/one/two'); $args_array = $route->getMapArguments(); $this->assertArrayHasKey(':id1', $args_array); $this->assertArrayHasKey(':id2', $args_array); }