Как обрабатывать AJAX-запросы и сеансы и подключения к БД? - PullRequest
2 голосов
/ 30 декабря 2011

Хорошо, лучший способ описать сценарий, который я знаю, - это сначала привести пример:

Скажем, у меня есть страница с именем index.php;

В самом верху перед тегом <html> можно найти;

<?php session_start();
 $_SESSION['user_id'] = 1234;
 require_once "db.con.php";
?>

Внутри тега <body> можно найти:

<div id="div_ajax">
<?php require_once "ajax.php"; ?>
</div>

Теперь внутри страницы ajax.php есть одна кнопка, при нажатии которой будет выполнен запрос ajax. После того, как запрос сделан, будет сделан простой оператор запроса Db для выбора информации пользователя на основе user_id. Дело в том, что после AJAX-запроса создается впечатление, что сеанс user_id и уже включенное соединение БД «потеряно».

Я знаю, что могу использовать условный оператор для проверки AJAX-запроса и просто добавить строки ...

session_start();
require_once "db.con.php";

.. вверху страницы ajax.php, но мне интересно, есть ли лучший способ сделать это? Я не хочу всегда добавлять эти две строки в каждый ajax, называемый страницей PHP. Это своего рода побеждает цель иметь строки на главной странице (index.php) для начала. Я полагаю, что могу использовать один ajax с именем page и просто включить кучу операторов case, но все еще задаюсь вопросом, есть ли лучший способ.

Большое спасибо.

Ответы [ 3 ]

0 голосов
/ 30 декабря 2011

Вы, кажется, запутались.

AJAX-запросы являются отдельными запросами для веб-страницы, ничего из того, что вы делали в index.php на стороне сервера, не будет доступно в последующих запросах (кромелюбые переменные в сеансе).Это работает так:

  1. Запрос на index.php отправляется из браузера
  2. Сервер запускает index.php (сохраняя user_id в сеансе) и возвращает вывод HTML в браузерв конце сценарий PHP завершается, и все ресурсы освобождаются.
  3. Пользователь нажимает кнопку, создавая новый запрос для другого файла PHP, например, ajax.php
  4. Сервер запускает ajax.php и возвращает все, что выводится в браузер.Снова PHP-скрипт завершается, и все ресурсы освобождаются.

Еще один способ думать об этом: со стороны сервера запрос AJAX почти такой же, как если бы вы только что указали браузеру на ajax.php напрямую.

0 голосов
/ 30 декабря 2011

Что касается моего опыта, я думаю, что ваша проблема может быть решена с помощью метода FrontController .

.

Основная идея заключается в том, что ваше приложение всегда вызывает один и тот же файл, например index.php (также называемый единой точкой входа).

index.php затем выполняет все задачи, которые вам нужны на каждой странице (например, начало сеанса или включая ваши библиотечные классы), а затем вызывает страницу, которую вы хотите запросить.

Это может выглядеть примерно так: (сейчас не могу проверить)

index.php:

<?php

    session_start();
    $_SESSION['user_id'] = 1234;
    require_once("db.con.php");


    if($_REQUEST['Request_Type'] == 'website'){
        require_once("header.html");

        switch($_REQUEST['Request_Url']){
            case 'SomePage':
                require('SomePage.php');
                break;
            case 'SomeOtherPage':
                require('SomeOtherPage.php');
                break;
            default:
                require('ajax.php');
        }

        require_once("footer.html");

    }elseif($_REQUEST['Request_Type'] == 'ajax'){
        switch($_REQUEST['Ajax_Function']){
            case 'ProcessButton':
                require('ProcessButton.php');
                break;
        }
    }

?>

ajax.php

echo '<input type="button" onClick="ajaxRequest(\"index.php\",\"ProcessButton\")" Value="ClickMe!" />';

Функция javascript ajaxRequest () должна была бы отправить Ajax-запрос в index.php, задав параметры
Request_Type = 'ajax'
Ajax_Function = 'ProcessButton'

0 голосов
/ 30 декабря 2011

Я не думаю, что есть лучший способ, но это не значит, что его нет.

Просто пара замечаний после прочтения вашего вопроса: 1) Используйте файлы-обертки для всехвашей информации заголовка.Итак, в начале вашей страницы поместите:

require_once('package.php'); // that's what I call mine

Затем в пакете я получу:

require_once('session.start.php');
require_once('db.con.php');

Таким образом, все ваши страницы обращаются к одной и той же вещи.Если вам когда-либо понадобится изменить его, это будет намного проще.

Существует разница в скорости между require_once, include_once, include и require.Я не знаю, насколько это важно.Фреймворки включают в себя более 60 файлов при создании страницы, поэтому я всегда считал, что это не так уж плохо.

Информация о сеансе хранится в папке на вашем сервере.PHP по умолчанию это / tmp (который вы должны изменить на личную папку / недоступен через Интернет).

Убедитесь, что вы проверяете любую информацию, отправленную в AJAX.Помните, что он похож на свою собственную веб-страницу, поэтому любые разрешения или конфиденциальная информация базы данных должны быть одинаково защищены.

"Я думаю, что я могу использовать один ajax-страницу и просто включить кучуcase case, но все еще задаюсь вопросом, есть ли лучший способ. "

Шаблон контроллера довольно хорош для такого типа вещей.Наличие нескольких регистров в одном файле сложно для вашего обслуживания.Когда вы переключитесь на файлы, в которых есть только 1 или 2 функции, ваша жизнь станет намного проще.

В зависимости от размера вашего проекта, вы можете захотеть реализовать фреймворк.Проверьте рамки MVC.Если я не реализую фреймворк, я все равно реализую шаблон контроллера.

Я поднял это из своего блога.То, что я сейчас использую, даже не выглядит так, но оно началось здесь:

На уровне презентации я определяю, какие элементы я хочу реализовать.Для каждого элемента, который я хочу реализовать, я запускаю контроллер, например, так:

    $controller = new Controller();
    $context = $controller->getContext();
    $context->addParam('action', 'login');
    $template->setContent( $controller->process() ); 

Я использую контроллер из объектов, шаблонов и практики PHP, 3-е издание, автор Matt Zandstraс моими собственными модификациями.

Вот что происходит:

  1. Мой уровень представления получает новый объект контроллера.
  2. Конструктор объекта Controller автоматически создает новый объект CommandContext.
  3. CommandContext автоматически будет загружать переменные запроса в качестве параметра, поэтому мне даже не нужно беспокоиться о данных формы, пока я не доберусь до уровня логики и не должен проверить иобработайте его.
  4. На уровне представления я загружаю любые дополнительные параметры контекста (или информацию, которую я хочу передать контроллеру), включая самое важное, действие, которое я хочу выполнить с помощьюКонтроллер.
  5. Чтобы передать информацию, я вызываю $ controller-> process ().В слое логики я могу использовать по умолчанию «выполнить» или сделать другую команду.Итак, на уровне Presentation я установил действие «Login», которое заставляет открываться страницы команды входа в систему и представления входа в систему, и команда по умолчанию выполняется, но это может быть что угодно.
  6. Когда я вызываю process, это вызывает CommandFacotry.CommandFactory собирается сначала инициировать новый дочерний объект Template, такой как блок div боковой панели или контекст основного тела.Это делается с помощью необязательного флага, который я могу передать контроллеру.
  7. Затем CommandFactory откроет командный файл и передаст шаблон и контекст в виде объектов на уровень логики.
    abstract class Command {

    }

    class CommandContext {
        private $params = array();
        private $error = "";

        function __construct(){
            $this->params = $_REQUEST;
        }

        function addParam( $key, $val ){
            $this->params[$key] = $val; 
        }

        function get( $key ){
            return $this->params[$key]; 
        }

        function issetCheck( $key ){
            if( ! empty( $this->params[$key] ) ){
                return true;
            }
            return false;
        }
        function setError( $error ){
            $this->error = $error;  
        }

        function getError(){
            return $this->error;    
        }
    }

    class CommandNotFoundException extends Exception { }

    class CommandFactory {
        private static $dir = 'include/classes/command/';

        static function getCommand( $action = 'Default', $flag = 0 ){

            switch( $flag ){
                case 1:
                    $template = new TemplateQuickViewOnly();
                    break;
                case 2:
                    $template = new TemplateQuickViewToggle();
                    break;
                default: 
                    $template = new TemplateMainBodyOnly();
                    break;
            }

            if( preg_match ( '/\W/', $action ) ){
                throw new Exception("illegal characters in action");    
            }

            $class = UCFirst(strtolower($action))."Command";
            $file = ROOT_PATH."".self::$dir."{$class}.php";
            if( ! file_exists( $file ) ){
                throw new CommandNotFoundException( "could not find '$file'" ); 
            }
            include_once( $file );
            if( ! class_exists($class) ){
                throw new CommandNotFoundException( "no '$class' class located" );  
            }
            $cmd = new $class( $template );

            return array( $cmd, $template );
        }
    }

    class Controller {
        private $context;

        function __construct(){
            $this->context = new CommandContext();
        }

        function getContext(){
            return $this->context;  
        }

        function process( $method = 'execute', $flag = 0 ){
            list( $cmd, $template ) = CommandFactory::getCommand( $this->context->get('action'), $flag );
            if( ! $cmd->$method( $this->context ) ){
                // handle failure
    //          $template->setMessage( UCFirst($this->context->get('action')).' failed to execute.');
                return $template->getMessage();
            }else{
                // success dispatch view
                return $template->getMessage();
            }
        }
    }

Уровень логики находится в фиксированном каталоге.Экземпляр объекта уже установлен на уровне контроллера, что означает, что конструктор был запущен.Кроме того, уровень контроллера уже вызвал метод «execute» (по умолчанию) или другой метод, такой как «getLoginForm».Также обратите внимание, что когда контроллер вызывает метод «execute», он также передает CommandContext методу, поэтому у нас есть кое-что для работы.

class LoginCommand extends Command {

    public function __construct( ){ }

    function execute ( CommandContext $context ){

        if( $context->get('login_user_name') == 'demo' ){
            $this->view->setMessage('Success is true!');
            return true;
        }
        return false;
    }

    function getLoginForm( CommandContext $context ){
        $this->view->setMessage('Second sucess is even more true!');
        return true;    
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...