草庐IT

php - 路由类无法正常工作

coder 2024-01-02 原文

我正在重写一个以前用 CodeIgniter 框架编写的应用程序,我的客户想要一个独立的应用程序和一个纯 php 代码。反正别告诉我不要重新发明轮子因为我已经知道我的客户错了。我们来解决问题。
我正在寻找一个简单的 Route 类,它允许我从任何位置调用任何文件。我发现了这个简单而强大的类,this is the repository .

我已经在我的项目中实现了它,复制 route.php索引位置内的文件并更改我的 .htaccess正如文档所说。而不是全部,这是我的项目的结构:

/ PUBLIC_HTML
   / application 
           / controllers
               /backend.php
               /user.php
           / helpers
           / models
           / views
               /backend
                   /backend.php
                   /calendar.php
               /user
                   /users.php
                   /panel.php
   / assets
           / files used by frontend...
   / system
           / configuration
           / constant
   / .htaccess
   / index.php
   / route.php
当 applicationi 从 index.php 启动时包含配置文件用于建立与数据库的连接。在同一 configuration文件我已经导入了 route.php .现在我的 index.php页面很简单,像这样:
// Check if the session is set

if(isset($_SESSION['user_info']['id_roles']))
{
    switch($_SESSION['user_info']['id_roles'])
    {
        case 1:         //Admin
            $route->add('/application/controllers/backend', 'index');
            $route->submit();
            break;
        case 2:         //Provider
            $route->add('/application/controllers/backend');
            $route->submit();
            break;
        case 3:         //Customer
            $route->add('/application/controllers/appointments');
            $route->submit();
            break;
    }
}
else
{
    // Session isn't set, so I redirect user to login page

    header('Location: application/views/user/login.php');
    exit; // stop
}
所以如果 session设置我将用户类型重定向到正确的位置,如果没有设置,我将显示登录页面。 login page 只是对 session 变量进行赋值,如果响应成功,用户将再次重定向到索引页面。

现在的问题是,例如当管理员被登录时(所以 case 1 ), route类不重视 $uri ,有点例子:
public function submit()
{
    $uri = isset($_REQUEST['uri']) ? $_REQUEST['uri'] : '/';
    $uri = trim($uri, $this->_trim);

    $replacementValues = array();

    // Iterate on the list of URI

    foreach($this->_listUri as $listKey => $listUri)
    {
        // Looking for a match..

        if(preg_match("#^$listUri$#", $uri))
        {
            // Replace the values

            $realUri = explode('/', $uri);
            $fakeUri = explode('/', $listUri);

            // Get value with .+ with real URI value

            foreach($fakeUri as $key => $value)
            {
                if ($value == '.+')
                {
                    $replacementValues[] = $realUri[$key];
                }
            }

            // Pass array arguments..

            call_user_func_array($this->_listCall[$listKey], $replacementValues);
        }
    }
}
check the full class here .$uri变量应该用当前 uri 进行赋值的服务器,但我尝试使用 var_dump 并得到一个空值。然后永远不会调用匹配条件,并且不显示正确的文件。我不知道为什么,我只是想了解为什么它不起作用,我可能做错了什么,有人可以帮助我理解吗?
完成管理员重定向的示例,我只想显示 backend.php 中包含的内容,应该从 route 加载.
<?php

  session_start();

  class Backend
  {
    // Construct of class
 
    public function __construct()
    {
    
    }

    // Display the main backend page

    public function index($appointment_hash = '')
    {
       $_SESSION['user_info']['hash'] = $appointment_hash;
       $_SESSION['user_info']['dest_url'] = SystemConfiguration::$base_url . "backend";
       // some content..
    }
 
    ...
所以你怎么看,我只想调用 index backend的功能我打电话时的 Controller ->add()用于添加要调用的 Controller 的url,和->submit()来执行操作。

我究竟做错了什么?
更新 - 路由器请求任务
首先,我更新了应用程序的堆栈。
我认为此时最好询问您的专家建议,了解哪个 OpenSource Router 允许我执行此任务:
1.导入 Controller
导入包含在我名为 controllers 的文件夹中的所有 Controller .导入后,我将简单地调用路由器的实例,并调用加载的 Controller 的特定功能。例子:
$router->backend->index();
哪里index();它代表了 Controller 的功能,名为backend .
这必须在我的整个应用程序中完成。此外,我会确保我们也可以通过 URL 调出该函数,特别是如果我插入这个 url:
localhost/application/controllers/backend/index
我可以简单地引用 url 来调用相同的函数。
2.请求ajax

Delivery My Router 必须能够从 javascript 运行 ajax 请求,尤其是当我使用以下代码时:
$('#login-form').submit(function(event)
    {

        var postUrl = GlobalVariables.baseUrl + 'user/ajax_check_login';
        var postData =
        {
            'username': $('#username').val(),
            'password': $('#password').val()
        };

        $('.alert').addClass('hidden');

        $.post(postUrl, postData, function(response)
        {
我想调用用户函数ajax_check_login .
包含在 Controller 中 user , 想象 GlobalVariables.baseUrl ,什么是...我们怎么能想到可以明显变化的基础应用程序的url。
请注意,我的 Controller 函数返回 json 格式。
3.加载 View
在我的应用程序中有 View ,保存在 .php 中, 但包含 html 文件,一个 View 示例(以前用 CodeIgniter 编写) pul 你会发现 here .
我希望能够调用 View 并显示新用户的 html 标记。我还需要同时调用更多 View ,例如有时我将主体分为:
header, body, footer
简化对什么的理解 $this指在 View 中,由于 View 是由 Controller 方法“加载”的,因此 View 仍然在与该方法相同的范围内运行,意思是 $this可以有不同的上下文,具体取决于加载它的类。
例如:
class Controller1 extends CI_Controller {}
在此示例 Controller 中加载的任何 View 文件中,$this特指Controller1类,可以访问CI_Controller公共(public)和 protected 属性/方法(如 Loader 或 Input 类,它们被分配给 CI_Controller 的加载和输入属性),因为它扩展了该类。
Controller 仍然只是普通的旧 PHP 类。如果我要这样做:
class Controller1 extends CI_Controller {
    $this->foobar = 'Hello';
}
class Controller2 extends CI_Controller {
    $this->foobar = 'World';
}
...如果我们在这些 Controller 中的任何一个的任何方法中加载相同的 View 文件,使用 $this->foobar在该 View 文件中将返回不同的值。
但这现在并不重要,我只想尽可能清楚。
我开始抽奖并失去所有代表,但我真的很想在这方面获得帮助并学习。

最佳答案

您需要以Router 提供的index.php 为例。您将看到如何设置路由:

  • 你总是必须有 2 个参数:1. uri, 2. 函数
  • 根据示例,函数必须不是函数名称 'index' ,而是一个函数体 function(){...} .也许引用也可以。
  • 路由恕我直言不应该依赖于 session (虽然它可能是,但这不是通常的做法)
  • 而不是 $router->backend->index(); ,我将在文件末尾有一个公共(public)代码块,因此您不必多次复制和粘贴代码。

  • 我会以你的方式向你展示后端,然后通过约会你如何让它变得普遍。所以你应该让你的路线像这样:
    <?php
    session_start();
    include 'route.php';
    $phpClass = false;
    $view = false;
    $func = false;
    $route = new Route();
    if(isset($_SESSION['user_info']) && isset($_SESSION['user_info']['id_roles'])) {
      $route->add('/application/controllers/backend', function(){
        echo 'You are now at backend page, and the role is ';
        switch($_SESSION['user_info']['id_roles']) {
          case 1: echo 'Admin'; break;
          case 2: echo 'Provider'; break;
          case 3: echo 'Customer'; break;
        }
        include 'backend.php';
        $backend = new Backend();
        $backend->index(/* I don't know what 'hash' could be */);
      });
    
      // more general case:
      $route->add('/application/controllers/appointments', function(){
        // we only set the global $phpClass variable, and the rest is common, see below
        global $phpClass, $func;
        $phpClass = 'Appointements';
        $func = 'index'; // default is index, if it wasn't given on the url
      });
      $route->add('/application/controllers/appointments/add', function(){
        // we only set the global $phpClass variable, and the rest is common, see below
        global $phpClass, $func;
        $phpClass = 'Appointements';
        $func = 'add';
      });
      $route->add('/application/controllers/appointments/delete', function(){
        // we only set the global $phpClass variable, and the rest is common, see below
        global $phpClass, $func;
        $phpClass = 'Appointements';
        $func = 'delete';
      });
      $route->add('/application/controllers/foo', function(){
        global $phpClass;
        $phpClass = 'Foo';
      });
      $route->add('/application/controllers/bar', function(){
        global $phpClass;
        $phpClass = 'Bar';
      });
    
      $route->add('/application/views/bar', function(){
        global $phpClass, $view;
        $phpClass = 'View';
        $func = 'show';
        $view = 'bar.php';
      });
    
      $route->submit();
    } else {
      // Session isn't set, so I redirect user to login page
      header('Location: /application/views/user/login.php');
      exit; // stop
    }
    
    if ($phpClass === false || $func === false) {
      die("You have to have both controller and function un the url");
    }
    
    // if we got here it means we're in the common case
    
    // include the necessary controller. If you want you can
    // include all of them at the top of the php and remove this line
    include 'application/controllers/' . strtolower($phpClass) . '.php';
    
    $controller = new $phpClass();
    
    // this is instead of `$router->backend->index();`:
    $controller->$func(/*$hash*/);
    // I don't know what '$hash' could be, maybe javascript could send it via ajax
    
    ?>
    

    Controller /view.php:
    class View {
        public function show() {
            global $view;
            include 'application/views/' . $view;
        }
    
        // here you'll need to have all the things that any of
        // your views access as $this->bar :
        $config = new stdClass(...);
        $array = array();
        function get_lang() {global $lang; return $lang;}
        //...
    }
    

    controller/user.php 中的 json 响应示例:
    class User {
        public function logged_in() {
            $username = isset($_SESSION) && isset($_SESSION['username']) ? $_SESSION['username'] : false;
            $response = array(
              'success' => $username !== false ? 'OK' : 'ERROR',
              'username' => $username
            );
            echo json_encode($response);
        }
    }
    

    关于php - 路由类无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35112533/

    有关php - 路由类无法正常工作的更多相关文章

    1. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

      我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

    2. ruby-on-rails - Rails 3 中的多个路由文件 - 2

      Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

    3. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

      我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

    4. ruby-on-rails - 无法使用 Rails 3.2 创建插件? - 2

      我对最新版本的Rails有疑问。我创建了一个新应用程序(railsnewMyProject),但我没有脚本/生成,只有脚本/rails,当我输入ruby./script/railsgeneratepluginmy_plugin"Couldnotfindgeneratorplugin.".你知道如何生成插件模板吗?没有这个命令可以创建插件吗?PS:我正在使用Rails3.2.1和ruby​​1.8.7[universal-darwin11.0] 最佳答案 随着Rails3.2.0的发布,插件生成器已经被移除。查看变更日志here.现在

    5. ruby - 无法运行 Rails 2.x 应用程序 - 2

      我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby​​:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r

    6. ruby-on-rails - 无法在centos上安装therubyracer(V8和GCC出错) - 2

      我正在尝试在我的centos服务器上安装therubyracer,但遇到了麻烦。$geminstalltherubyracerBuildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingtherubyracer:ERROR:Failedtobuildgemnativeextension./usr/local/rvm/rubies/ruby-1.9.3-p125/bin/rubyextconf.rbcheckingformain()in-lpthread...yescheckingforv8.h...no***e

    7. ruby - 无法让 RSpec 工作—— 'require' : cannot load such file - 2

      我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳

    8. ruby-on-rails - rspec should have_select ('cars' , :options => ['volvo' , 'saab' ] 不工作 - 2

      关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request

    9. ruby-on-rails - s3_direct_upload 在生产服务器中不工作 - 2

      在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo

    10. ruby - 无法覆盖 irb 中的 to_s - 2

      我在pry中定义了一个函数:to_s,但我无法调用它。这个方法去哪里了,怎么调用?pry(main)>defto_spry(main)*'hello'pry(main)*endpry(main)>to_s=>"main"我的ruby版本是2.1.2看了一些答案和搜索后,我认为我得到了正确的答案:这个方法用在什么地方?在irb或pry中定义方法时,会转到Object.instance_methods[1]pry(main)>defto_s[1]pry(main)*'hello'[1]pry(main)*end=>:to_s[2]pry(main)>defhello[2]pry(main)

    随机推荐