Ошибка получения неопределенного индекса и имя метода должны быть строкой в ​​..error в PHP - PullRequest
0 голосов
/ 02 сентября 2018

При обновлении до PHP7 я столкнулся с этой проблемой.

Проблема в том, что я пытаюсь создать коды, которые я могу использовать повторно, например, в качестве мини-фреймворка и функции RUN, где проблема используется для загрузки соответствующего шаблона и предоставления переменных. Жалуется на

неопределенный индекс

из этих 2 переменных

$controller = $routes[$this->route][$this->method]['controller'];
$action = $routes[$this->route][$this->method]['action'];

и он также жаловался на эту строку

$page = $controller->$action(); 

, который отображается

Неустранимая ошибка: необученная ошибка: имя метода должно быть строкой в ​​...

public function run() {

            $routes = $this->routes->getRoutes();   

            $authentication = $this->routes->getAuthentication();

            if (isset($routes[$this->route]['login']) && !$authentication->isLoggedIn()) {
                header('location: /login/error');
            }
            else if (isset($routes[$this->route]['permissions']) && !$this->routes->checkPermission($routes[$this->route]['permissions'])) {
                header('location: /login/permissionserror');    
            }
            else {
                            $controller = $routes[$this->route][$this->method]['controller'];
                            $action = $routes[$this->route][$this->method]['action']; 
                            $page = $controller->$action();
                $title = $page['title'];

                if (isset($page['variables'])) {
                    $output = $this->loadTemplate($page['template'], $page['variables']);
                }
                else {
                    $output = $this->loadTemplate($page['template']);
                }

                echo $this->loadTemplate('layout.html.php', ['loggedIn' => $authentication->isLoggedIn(),
                                                             'output' => $output,
                                                             'title' => $title
                                                            ]);

            }

Это index.php

try {
    include __DIR__ . '/../includes/autoload.php';

    $route = ltrim(strtok($_SERVER['REQUEST_URI'], '?'), '/');

    $entryPoint = new \Ninja\EntryPoint($route, $_SERVER['REQUEST_METHOD'], new \Ijdb\IjdbRoutes());
    $entryPoint->run();
}
catch (PDOException $e) {
    $title = 'An error has occurred';

    $output = 'Database error: ' . $e->getMessage() . ' in ' .
    $e->getFile() . ':' . $e->getLine();

    include  __DIR__ . '/../templates/layout.html.php';
}

кода много, поэтому я не могу отобразить весь код здесь, так как я использую шаблон MVC, но если есть что-то, что вы все еще хотите знать, я с удовольствием выложу его здесь

Ответы [ 2 ]

0 голосов
/ 05 сентября 2018

Этот код работает в php 7.2.7 (MAMP и LAMP), ваш способ динамического вызова функции недопустим, а две ваши переменные пусты. Это не совсем так, как у вас, но вы можете взять логику из этой демонстрации.

Хорошо, я просто предоставляю очень простой пример отражения с отображением URL в класс вместе с функциями. Я делаю структуру папок, как показано ниже: folder structure of the image

  1. Здесь .htaccess используется для перенаправления всего URL-адреса в index.php (если файл не существует).
  2. index.php включает в себя весь код, который может инициализировать код (на данный момент там было только три файла - uri.php, urlMapping.php и actions.php)
  3. URI.php - есть функция, предоставляющая такие значения, как basepath, baseurl, uri
  4. urlMappig.php - позволяет указать, какой URL-адрес попадет в какой класс вместе с методом
  5. actions.php вызовет динамический класс и функцию (отражение)

теперь посмотрите в код index.php

    <?php
        include_once('URI.php');
        include_once('urlMapping.php');
        include_once('actions.php');

    ?>

Теперь код insise uri.php file -

<?php
   // all function should be accessible to all file loaded now
   // return full url
    function full_url (){ 
        return (isset($_SERVER['HTTPS']) ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
    }
    // returns current directory
    function directory() {
        $parts = explode("/", __DIR__);
        return $parts[count($parts)-1];
    }
    // return base url
    function base_url(){ 
        $dir = directory();
        return  substr(full_url(), 0, strpos(full_url(), $dir)+strlen($dir));
    }
    // return uri
    function uri() { 
        return substr(full_url(), strlen(base_url())+1);
    }
?>

Теперь код в urlMapping.php

Примечание. Имя файла и имя класса должны совпадать с URL-адресом карты в этот файл, чтобы вы могли вызывать динамические классы и функции на actions.php. Если нет, это не сработает

<?php
    // this $urlMap will be accessed in actions.php
    $urlMap = [
        // here we use only uri so .. https://example.com/login hit LoginController class along with login function, this is just only the mapping
        'login' => ['class'=>'LoginController',
                    'function'=>'login'],
    ];
?>

Теперь код actions.php

<?php
    // if call is not like example.com/ means no uri is there
    if(uri()!='')
    {
        // if your uri exists in route collection or urlmapping collection then make call to your dynamic class and methods
        if(array_key_exists(uri(), $urlMap))
        {
            // include the class file dynamically from controllers folder
            include_once('controllers/'.$urlMap[uri()]['class'].'.php');
            // making references for dynamic class
            $controlerObject = new $urlMap[uri()]['class']();
            // call function dynaically from the referece
            $controlerObject->{$urlMap[uri()]['function']}();           

        }
        else
        {
            // you can make 404 page not
            echo 'No routing found';
        }
    }
    // call for home page 
    else
    {
        include_once('index.html.php');
    }
?>

Теперь controllres / класс LoginController.php,

Примечание. Как уже упоминалось выше, имя файла и имя класса, как в urlMapping.php

<?php
    class LoginController{
        public function login()
        {
            // .... something your code goes here

            echo 'hello from the login function of login controller';
        }
        //...... other function you can define
    }
?>
0 голосов
/ 02 сентября 2018

Перед звонком $page = $controller->$action(); проверьте, существуют ли controller и action:

if (isset($routes[$this->route][$this->method]['controller']) 
    && isset($routes[$this->route][$this->method]['action'])) {
    $controller = $routes[$this->route][$this->method]['controller'];
    $action = $routes[$this->route][$this->method]['action'];
    $page = $controller->$action();
    // ...
} else {
   // return 404 Page not found
}
...