Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/249.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何在类似MVC的页面中加载基于漂亮URL的类?_Php_.htaccess_Url Routing - Fatal编程技术网

Php 如何在类似MVC的页面中加载基于漂亮URL的类?

Php 如何在类似MVC的页面中加载基于漂亮URL的类?,php,.htaccess,url-routing,Php,.htaccess,Url Routing,我想问一些关于如何解决这个问题的建议。我正在尝试建立我自己的MVC网站。我学习了URL的基本知识 http://example.com/blog/cosplay/cosplayer-expo-today blog->controllercosplay->controller中的方法cosplayer expo today->variable in method 如果我在我的博客控制器中动态扩展类别会怎么样?我是否需要创建该方法,或者是否有一些技巧可以自动创建该方法?我是说。。。我现在有这些类别

我想问一些关于如何解决这个问题的建议。我正在尝试建立我自己的MVC网站。我学习了URL的基本知识

http://example.com/blog/cosplay/cosplayer-expo-today
blog->controller
cosplay->controller中的方法
cosplayer expo today->variable in method

如果我在我的博客控制器中动态扩展类别会怎么样?我是否需要创建该方法,或者是否有一些技巧可以自动创建该方法?我是说。。。我现在有这些类别:角色扮演,游戏,电影,系列。所以我需要在controller中创建这些方法,但它们都做相同的事情,即从数据库中选择其他类别

  • 函数cosplay()=example.com/blog/cosplay/
  • 函数game()=example.com/blog/game/
  • 函数movie()=example.com/blog/movie/
  • 函数系列()=example.com/blog/series/
关于如何编写控制器以自动执行此操作,有什么好的建议吗?我的意思是,如果我在数据库中上传一个新类别,但我不想修改控制器。可能吗?谢谢你的帮助

更新

这是我的URL爆炸器类

class Autoload
{
    var $url;
    var $controller;
    function __construct()
    {
        $this->url = $_GET['url'];
        //HNEM ÜRES AZ URL
        if($this->url!='' && !empty($this->url))
        {
            require 'application/config/routes.php';
            //URL VIZSGÁLATA
            $this->rewrite_url($this->url);

            //URL SZÉTBONTÁSA
            $this->url = explode('/', $this->url);

            $file = 'application/controllers/'.$this->url[0].'.php';
            //LÉTEZIK A CONTROLLER?
            if(file_exists($file))
            {
                require $file;
                $this->controller = new $this->url[0];

                //KÉRELEM ALATT VAN AZ ALOLDAL?
                if(isset($this->url[1]))
                {
                    //LÉTEZIK A METÓDUS? ENGEDÉLYEZVE VAN?
                    if(method_exists($this->controller, $this->url[1]) && in_array($this->url[1], $route[$this->url[0]]))
                    {
                        if(isset($this->url[2]))
                        {
                            $this->controller->{$this->url[1]}($this->url[2]);
                        }
                        else
                        {
                            $this->controller->{$this->url[1]}();
                        }
                    }
                    else
                    {
                        header('location:'.SITE.$this->url[0]);
                        die();
                    }
                }
            }
            else
            {
                header('location:'.SITE);
                die();
            }
        }
        else
        {
            header('location:'.SITE.'blog');
            die();
        }
    }

    /**
     * Első lépésben megvizsgáljuk, hogy a kapott szöveg tartalmaz-e nagybetűt. Amennyiben igen átalakítjuk kisbetűsre.<br/>
     * Második lépésben megnézzük, hogy a kapott szöveg '/'-re végződik-e. Amennyiben igen levágjuk azt.<br/>
     * Harmadik lépésben újra töltjük az oldalt a formázott szöveggel.
     * 
     * @param string $url Korábban beolvasott URL.
     */
    private function rewrite_url($url)
    {
        //HA NAGYBETŰ VAN AZ URL-BEN VAGY '/'-RE VÉGZŐDIK
        if(preg_match('/[A-Z]/', $url) || substr($url, -1)=='/')
        {
            //NAGYBETŰS AZ URL KICSIRE ALAKÍTJUK
            if(preg_match('/[A-Z]/', $url))
            {
                $url = strtolower($url);
            }
            //HA '/'-RE VÉGZŐDIK LEVÁGJUK
            if(substr($url, -1)=='/')
            {
                $url = substr($url, 0, strlen($url)-1);
            }
            header('location:'.SITE.$url);
            die();
        }
    }




}

我想你对这件事想得太多了

因此,控制器/资源是一个blog…所有控制器/资源运行的方法都是“read”(使用crud…我通常称之为data,但基本上是您自己选择的)。现在,让您的方法接受一个类别值,该值将根据url自动映射

这是一个示例…完全未经测试,但只是为了向您展示这个想法(使用pdo)

仅供参考:有几件事你做错了。我将试着逐一解释问题、误解和可能的解决方案

自动加载和路由是分开的。 从您发布的代码来看,很明显,您只有一个类,负责以下任务:

  • 路由:它将URL拆分为对其他应用程序有一定意义的部分
  • 自动加载:类接受分离的URL段并尝试包含相关代码
  • 工厂:初始化新实例并对其调用某些方法
  • 响应:在某些情况下,类以HTTP头的形式向用户发送响应
在OOP中有一个东西,叫做:[]。基本上,它意味着一个类应该处理一个特定的are对象。以上列表构成了您的
自动加载类至少4个不同的职责

这些常规任务中的每一个都应该由单独的类来处理,而不是您现在所拥有的。在自动加载器的情况下,你只需一个功能就可以脱身

如何编写自己的自动加载代码? 我看到的部分问题是关于自动加载在PHP中实际如何工作的混淆。在创建实例的地方不需要调用
include
require
。相反,您注册了一个处理程序(使用函数),当您尝试使用以前未定义的类时,会**自动*调用该处理程序

最简单的例子是:

spl_autoload_register( function( $name ) use ( $path ) {
    $filename = $path . '/' . $name . '.php';
    if ( file_exists( $filename ) === true ) {
        require $filename;
        return true;
    }
    return false;
});
这个特定的示例使用了,这是PHP5.3中引入的功能之一,但是
spl\u autoload\u register()
的手册页面也将向您展示如何使用对象或普通函数实现相同的功能

另一个与自动加载密切相关的新特性是。在这种情况下,名称空间将给您带来两个直接的好处:能够拥有多个同名类,以及从多个目录加载类文件的选项

例如,您可以使用如下代码:

$controller = new \Controllers\Overview;
$view = new \Views\Overview;

$controller->doSomething( $request );
。。在这种情况下,您可以让autoloader分别从
/project/controllers/overview.php
/project/views/overview.php
文件获取类。因为
spl\u autoload\u register()
“\Controllers\Overview”
“\Views\Overview”
传递给处理程序函数

还有一个关于如何实现自动加载器的建议。你可以找到它。虽然它有一些重大问题,但它应该为您提供一个良好的基础

如何解析漂亮的URL? Apache的mod_重写在处理漂亮的URL方面非常有限,这不是什么秘密。而且,虽然它是一个广泛使用的服务器,但它不是Web服务器的唯一选择。这就是为什么为了获得最大的灵活性,PHP开发人员选择在PHP端处理URL

任何新手都会做的第一件事就是爆炸('/',…)
。这是一个自然的选择,但您很快就会注意到,它的实际功能也非常有限。路由机制将开始增长。首先基于段数,然后在段中添加需要不同行为的不同条件值

从本质上讲,这将导致巨大、脆弱和无法控制的混乱局面。坏主意

相反,您应该做的是有一个正则表达式列表,您可以根据给定的漂亮URL进行匹配。例如:

'#/(?P<resource>[^/\\\\.,;?\n]+)/foobar#'
您可以使用以下代码来处理:

// CHANGE THIS
$url = '/12345/product';

$current = null;

// matching the route
foreach ($routes as $name => $route) {
    $matches = [];
    if ( preg_match( $route['pattern'], $url, $matches ) ) {
        $current = $name;
        $matches = $matches + $route['default'];
        break;
    }
}


// cleaning up results
foreach ( array_keys($matches) as $key ) {
    if ( is_numeric($key) ) {
        unset( $matches[$key] );
    }
}


// view results
var_dump( $current, $matches );
实时代码:或

注意:
如果使用
'(?p…)
符号,匹配项将返回带有
'name'
键的数组。比路由更有用的技巧

您可能希望从一些可读性更强的符号生成匹配的正则表达式。例如,在配置文件中,此表达式:

'#^/(?P<id>[0-9]+)(?:/(?P<resource>[^/\\\\.,;?\n]+)(?:/(?P<action>[^/\\\\.,;?\n]+))?)?$#'
其中,
:param
表示URL段,
[…]
表示URL的可选部分

基于此,您应该能够充实自己的路由系统。上面的代码片段只是简化核心功能的示例。要了解它在完全实现时的外观,可以查看中的代码。它应该给你这样的机会
$routes = [
    'primary' => [
        'pattern'   => '#/(?P<resource>[^/\\\\.,;?\n]+)/foobar#',
        'default'   => [
            'action'    => 'standard',
        ],
    ],
    'secundary' => [
        'pattern'   => '#^/(?P<id>[0-9]+)(?:/(?P<resource>[^/\\\\.,;?\n]+)(?:/(?P<action>[^/\\\\.,;?\n]+))?)?$#',
        'default'   => [
            'resource'  => 'catalog',
            'action'    => 'view',
        ]
    ],
    'fallback'  => [
        'pattern'   => '#^.*$#',
        'default'   => [
            'resource'  => 'main',
            'action'    => 'landing',
        ],
    ],
]; 
// CHANGE THIS
$url = '/12345/product';

$current = null;

// matching the route
foreach ($routes as $name => $route) {
    $matches = [];
    if ( preg_match( $route['pattern'], $url, $matches ) ) {
        $current = $name;
        $matches = $matches + $route['default'];
        break;
    }
}


// cleaning up results
foreach ( array_keys($matches) as $key ) {
    if ( is_numeric($key) ) {
        unset( $matches[$key] );
    }
}


// view results
var_dump( $current, $matches );
'#^/(?P<id>[0-9]+)(?:/(?P<resource>[^/\\\\.,;?\n]+)(?:/(?P<action>[^/\\\\.,;?\n]+))?)?$#'
'/:id[[/:resource]/:action]'
$matches = $router->parse( $url );

$controller = new {'\\Controller\\'.$matches['controller']};
$controller->{$matches['action']( $matches );
public function getCategory( $request ) {
    $category = $request->getParameter('category');

    // ... rest of your controller method's code
}