2009-01-11 2 views
9

В Java я могу написать действительно основной JSP index.jsp так:Имеет ли PHP эквивалент Java RequestDispatcher.forward?

<% request.getRequestDispatcher("/home.action").forward(request, response); %>

Эффект этого является то, что пользователь, запрашивающий index.jsp (или просто содержащий каталог при условии index.jsp является документ по умолчанию для каталога) будет видеть home.action без браузера редирект, то есть [вперед] (http://java.sun.com/javaee/5/docs/api/javax/servlet/RequestDispatcher.html#forward(javax.servlet.ServletRequest,%20javax.servlet.ServletResponse)) происходит на стороне сервера.

Могу ли я сделать что-то подобное с PHP? Я подозреваю, что это можно настроить Apache обрабатывать этот случай, но так как я не мог бы имеют доступ к соответствующему Apache con figuration Мне было бы интересно решение, основанное только на PHP.

ответ

0

Если вас беспокоит наличие CURL, вы можете использовать file_get_contents() и потоки.Настройка функции как:

function forward($location, $vars = array()) 
{ 
    $file ='http://'.$_SERVER['HTTP_HOST'] 
    .substr($_SERVER['REQUEST_URI'],0,strrpos($_SERVER['REQUEST_URI'], '/')+1) 
    .$location; 

    if(!empty($vars)) 
    { 
     $file .="?".http_build_query($vars); 
    } 

    $response = file_get_contents($file); 

    echo $response; 
} 

Это просто устанавливает GET, но вы можете сделать пост с file_get_contents(), а также.

+0

С этим подходом многое не так. Во-первых, он не будет проходить по любым заголовкам, и он будет работать только с запросом типа GET. – troelskn

+0

, и он с ужасом потерпит неудачу, если PHP работает в безопасном режиме ... – SchizoDuckie

+0

... еще не принято: D –

-3

Вы можете использовать как:

header ("Location: /path/"); 
exit; 

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

+0

Это решение включает клиента, что не относится к внутренней переадресации. – MatthieuP

1

Уловка запроса Request.Forward заключается в том, что она дает вам чистый новый запрос на нужное действие. Поэтому у вас нет остатка от текущего запроса и, например, никаких проблем с скриптами, которые полагаются на java eq из $ _SERVER ['REQUEST_URI'].

Вы можете просто бросить в классе CURL и написать простую функцию, чтобы сделать это:

<?php 
/** 
* CURLHandler handles simple HTTP GETs and POSTs via Curl 
* 
* @author SchizoDuckie 
* @version 1.0 
* @access public 
*/ 
class CURLHandler 
{ 

    /** 
    * CURLHandler::Get() 
    * 
    * Executes a standard GET request via Curl. 
    * Static function, so that you can use: CurlHandler::Get('http://www.google.com'); 
    * 
    * @param string $url url to get 
    * @return string HTML output 
    */ 
    public static function Get($url) 
    { 
     return self::doRequest('GET', $url); 
    } 

    /** 
    * CURLHandler::Post() 
    * 
    * Executes a standard POST request via Curl. 
    * Static function, so you can use CurlHandler::Post('http://www.google.com', array('q'=>'belfabriek')); 
    * If you want to send a File via post (to e.g. PHP's $_FILES), prefix the value of an item with an @ ! 
    * @param string $url url to post data to 
    * @param Array $vars Array with key=>value pairs to post. 
    * @return string HTML output 
    */ 
    public static function Post($url, $vars, $auth = false) 
    { 
     return self::doRequest('POST', $url, $vars, $auth); 
    } 

    /** 
    * CURLHandler::doRequest() 
    * This is what actually does the request 
    * <pre> 
    * - Create Curl handle with curl_init 
    * - Set options like CURLOPT_URL, CURLOPT_RETURNTRANSFER and CURLOPT_HEADER 
    * - Set eventual optional options (like CURLOPT_POST and CURLOPT_POSTFIELDS) 
    * - Call curl_exec on the interface 
    * - Close the connection 
    * - Return the result or throw an exception. 
    * </pre> 
    * @param mixed $method Request Method (Get/ Post) 
    * @param mixed $url URI to get or post to 
    * @param mixed $vars Array of variables (only mandatory in POST requests) 
    * @return string HTML output 
    */ 
    public static function doRequest($method, $url, $vars=array(), $auth = false) 
    { 
     $curlInterface = curl_init(); 

     curl_setopt_array ($curlInterface, array( 
      CURLOPT_URL => $url, 
      CURLOPT_CONNECTTIMEOUT => 2, 
      CURLOPT_RETURNTRANSFER => 1, 
      CURLOPT_FOLLOWLOCATION =>1, 
      CURLOPT_HEADER => 0)); 

     if (strtoupper($method) == 'POST') 
     { 
      curl_setopt_array($curlInterface, array(
       CURLOPT_POST => 1, 
       CURLOPT_POSTFIELDS => http_build_query($vars)) 
      ); 
     } 
     if($auth !== false) 
     { 
       curl_setopt($curlInterface, CURLOPT_USERPWD, $auth['username'] . ":" . $auth['password']); 
     } 
     $result = curl_exec ($curlInterface); 
     curl_close ($curlInterface); 

     if($result === NULL) 
     { 
      throw new Exception('Curl Request Error: '.curl_errno($curlInterface) . " - " . curl_error($curlInterface)); 
     } 
     else 
     { 
      return($result); 
     } 
    } 

} 

Просто бросьте это в class.CURLHandler.php, и вы можете сделать это:

конечно, используя $ _REQUEST не очень безопасен (вы должны проверить $ _SERVER ['REQUEST_METHOD']), но вы понимаете.

<?php 
include('class.CURLHandler.php'); 
die CURLHandler::doRequest($_SERVER['REQUEST_METHOD'], 'http://server/myaction', $_REQUEST); 
?> 

Ofcourse, CURL не установлен везде но у нас есть native PHP curl emulators for that.

Кроме того, это дает вам еще больше гибкости, чем Request.Forward, как вы могли бы также поймать и постобработку выход.

+0

curl не включен по умолчанию в php. Также завиток сделает другой запрос http-запроса означающим больше использования процессора. – Ivan

+0

Да, но .forward делает что-то вроде этого тоже FAIK. У вас нет экологического материала, связанного с текущим запросом. Следовательно, должен произойти другой «HTTP-запрос», вы не хотите выполнять этот скрипт в той же области. поскольку это может вызвать проблемы с определенными переменными. – SchizoDuckie

1

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

виртуальный() является Апач-специфическая функция, которая похожа на в mod_include. Он выполняет подпроцесс Apache .

1

Если вы используете MVC, как Zend Framework, вы можете изменить действие контроллера или даже перейти между действиями контроллера. Метод _forward равен described here.

1

Попробуйте это.

function forward($page, $vars = null){ 
    ob_clean(); 
    include($page); 
    exit; 
} 

на включенной странице переменная $vars будет работать как запрос Java атрибуты

0

понятия Перенаправление и вперед, как в Java, может быть достижимо в PHP тоже.

Перенаправление :: header("Location: redirect.php"); - (URL в адресной строке изменения)

Вперед :: include forward.php ; - (URL без изменений в адресной строке)

его управляемым с этим & других логик программирования

Смежные вопросы