Php instanceof Closure返回false

Php instanceof Closure返回false,php,routing,closures,instanceof,Php,Routing,Closures,Instanceof,在我的应用程序的路由部分,我有Route和Router类,Route只保存有关特定映射路由的信息以及设置和获取这些信息的方法。 我正试图通过这样的结束 Router::map('/', function(){}, array()); 我存储第二个参数(闭包),如下所示 $route = new Route(); $route->setTarget($target); *第二个参数是$target变量 当我尝试这个的时候 $target = $route->getTarget();

在我的应用程序的路由部分,我有Route和Router类,Route只保存有关特定映射路由的信息以及设置和获取这些信息的方法。 我正试图通过这样的结束

Router::map('/', function(){}, array());
我存储第二个参数(闭包),如下所示

$route = new Route();
$route->setTarget($target);
*第二个参数是$target变量

当我尝试这个的时候

$target = $route->getTarget();
if($target instanceof Closure)
{
   echo 1;
}else
{
   echo 0;
}
它打印0,但当我尝试打印($target)时,我得到

Closure Object ( ) 
班级路线

class Route {

    /**
    * URL of this Route
    * @var string
    */
    private $url;

    /**
    * Accepted HTTP methods for this route
    * @var array
    */
    private $methods = array('GET','POST','PUT','DELETE');

    /**
    * Target for this route, can be anything.
    * @var mixed
    */
    private $target;

    /**
    * The name of this route, used for reversed routing
    * @var string
    */
    private $name;

    /**
    * Custom parameter filters for this route
    * @var array
    */
    private $filters = array();

    /**
    * Array containing parameters passed through request URL
    * @var array
    */
    private $params = array();

    public function getUrl() {
        return $this->url;
    }

    public function setUrl($url) {
        $url = (string) $url;

        // make sure that the URL is suffixed with a forward slash
        if(substr($url,-1) !== '/') $url .= '/';

        $this->url = $url;
    }

    public function getTarget() {
        return $this->target;
    }

    public function setTarget($target) {
        $this->target = $target;
    }

    public function getMethods() {
        return $this->methods;
    }

    public function setMethods(array $methods) {
        $this->methods = $methods;
    }

    public function getName() {
        return $this->name;
    }

    public function setName($name) {
        $this->name = (string) $name;
    }

    public function setFilters(array $filters) {
        $this->filters = $filters;
    }

    public function getRegex() {
        return preg_replace_callback("/:(\w+)/", array(&$this, 'substituteFilter'), $this->url);
    }

    private function substituteFilter($matches) {
        if (isset($matches[1]) && isset($this->filters[$matches[1]])) {
                return $this->filters[$matches[1]];
            }

            return "([\w-]+)";
    }

    public function getParameters() {
        return $this->parameters;
    }

    public function setParameters(array $parameters) {
        $this->parameters = $parameters;
    }




}
类路由器

    class Router {

    /**
    * Array that holds all Route objects
    * @var array
    */ 
    private static $_routes = array();

    /**
     * Array to store named routes in, used for reverse routing.
     * @var array 
     */
    private static $_namedRoutes = array();

    /**
     * The base REQUEST_URI. Gets prepended to all route url's.
     * @var string
     */
    private static $_basePath = '';

    /**
     * Set the base url - gets prepended to all route url's.
     * @param string $base_url 
     */
    public function setBasePath($basePath) {
        static::$_basePath = (string) $basePath;
    }

    /**
    * Route factory method
    *
    * Maps the given URL to the given target.
    * @param string $routeUrl string
    * @param mixed $target The target of this route. Can be anything. You'll have to provide your own method to turn *      this into a filename, controller / action pair, etc..
    * @param array $args Array of optional arguments.
    */
    public static function map($routeUrl, $target, array $args = array()) {
        $route = new Route();

        $route->setUrl(static::$_basePath . $routeUrl);

        $route->setTarget($target);

        if(isset($args['methods'])) {
            $methods = explode(',', $args['methods']);
            $route->setMethods($methods);
        }

        if(isset($args['filters'])) {
            $route->setFilters($args['filters']);
        }

        if(isset($args['name'])) {
            $route->setName($args['name']);
            if (!isset(static::$_namedRoutes[$route->getName()])) {
                static::$_namedRoutes[$route->getName()] = $route;
            }
        }

        static::$_routes[] = $route;
    }

    /**
    * Matches the current request against mapped routes
    */
    public static function matchCurrentRequest() {
        $requestMethod = (isset($_POST['_method']) && ($_method = strtoupper($_POST['_method'])) && in_array($_method,array('PUT','DELETE'))) ? $_method : $_SERVER['REQUEST_METHOD'];
        $requestUrl = $_SERVER['REQUEST_URI'];

        // strip GET variables from URL
        if(($pos = strpos($requestUrl, '?')) !== false) {
            $requestUrl =  substr($requestUrl, 0, $pos);
        }

        return static::match($requestUrl, $requestMethod);
    }

    /**
    * Match given request url and request method and see if a route has been defined for it
    * If so, return route's target
    * If called multiple times
    */
    public static function match($requestUrl, $requestMethod = 'GET') {

        foreach(static::$_routes as $route) {

            // compare server request method with route's allowed http methods
            if(!in_array($requestMethod, $route->getMethods())) continue;

            // check if request url matches route regex. if not, return false.
            if (!preg_match("@^".$route->getRegex()."*$@i", $requestUrl, $matches)) continue;

            $params = array();

            if (preg_match_all("/:([\w-]+)/", $route->getUrl(), $argument_keys)) {

                // grab array with matches
                $argument_keys = $argument_keys[1];

                // loop trough parameter names, store matching value in $params array
                foreach ($argument_keys as $key => $name) {
                    if (isset($matches[$key + 1]))
                        $params[$name] = $matches[$key + 1];
                }

            }

            $route->setParameters($params);

            if($route)
            {
                static::respond($route);
            }
            return $route;



        }

        return false;
    }



    /**
     * Reverse route a named route
     * 
     * @param string $route_name The name of the route to reverse route.
     * @param array $params Optional array of parameters to use in URL
     * @return string The url to the route
     */
    public function generate($routeName, array $params = array()) {
        // Check if route exists
        if (!isset(static::$_namedRoutes[$routeName]))
            throw new Exception("No route with the name $routeName has been found.");

        $route = static::$_namedRoutes[$routeName];
        $url = $route->getUrl();

        // replace route url with given parameters
        if ($params && preg_match_all("/:(\w+)/", $url, $param_keys)) {

            // grab array with matches
            $param_keys = $param_keys[1];

            // loop trough parameter names, store matching value in $params array
            foreach ($param_keys as $i => $key) {
                if (isset($params[$key]))
                    $url = preg_replace("/:(\w+)/", $params[$key], $url, 1);
            }
        }

        return $url;
    }

    private static function respond($route)
    {
        $target = $route->getTarget();
        $path   = null;

        if($target instanceof Closure)
        {
            call_user_func($target);

        }else
        {
            if(is_string($target))
            {
                $target         = explode('@', $target);
                $target[0]      = explode(':', $target[0]);
                $controller     = $target[0][0];
                $method         = $target[0][1];
                $application    = $target[1];
                $path           = path('app') . $application . '/controllers/' . ucfirst($controller) . '.php'; 

            }

            if(is_array($target))
            {
                $controller     = $target['controller'];
                $method         = $target['method'];
                $application    = $target['application'];
                $path           = path('app') . $application . '/controllers/' . ucfirst($controller) . '.php'; 
            }


            if(file_exists($path))
            {
                $obj = require($path);
                $obj = new $controller();
                $obj->$method();
            }else
            {
                echo '404';
            }
        }
    }

}

您是否在代码中使用名称空间


如果是这样,您需要将闭包类名指定为
\Closure
,以跳转到全局名称空间。

请考虑将代码简化为一个更简洁的示例。当这样做时,。在主题上,IMHO
instanceof Closure
不是编写代码的好方法,因为它假设了太多。在我自己的代码中,我总是使用
is\u object($c)&&is\u callable($c)
。您是否在命名空间中?再次检查类型,确保同时使用
var\u dump
。快速测试成功:-此外,@Jon提出了一个很好的观点..问题是名称空间,是的,你应该将Danack的答案标记为解决方案!该死,我完全忘了名字空间,你是救命恩人