简体   繁体   English

PHP是否具有Java的RequestDispatcher.forward等价物?

[英]Does PHP Have an Equivalent of Java's RequestDispatcher.forward?

In Java I can write a really basic JSP index.jsp like so: 在Java中,我可以编写一个非常基本的JSP index.jsp如下所示:

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

The effect of this is that a user requesting index.jsp (or just the containing directory assuming index.jsp is a default document for the directory) will see home.action without a browser redirect, ie the [forward]( http://java.sun.com/javaee/5/docs/api/javax/servlet/RequestDispatcher.html#forward(javax.servlet.ServletRequest,%20javax.servlet.ServletResponse)) happens on the server side. 这样做的结果是请求index.jsp的用户(或者只是假设index.jsp是目录的默认文档的包含目录)将看到home.action而没有浏览器重定向,即[forward]( http:// java.sun.com/javaee/5/docs/api/javax/servlet/RequestDispatcher.html#forward(javax.servlet.ServletRequest,%20javax.servlet.ServletResponse))发生在服务器端。

Can I do something similar with PHP? 我可以用PHP做类似的事吗? I suspect it's possible to configure Apache to handle this case, but since I might not have access to the relevant Apache configuration I'd be interested in a solution that relies on PHP alone. 我怀疑可以配置Apache来处理这种情况,但由于我可能无法访问相关的Apache配置,所以我会对依赖于PHP的解决方案感兴趣。

The trick about Request.Forward is that it gives you a clean, new request to the action you want. 关于Request.Forward的诀窍在于它为您提供了一个干净的新请求。 Therefore you have no residu from the current request, and for example, no problems with scripts that rely on the java eq of $_SERVER['REQUEST_URI'] being something. 因此,您没有当前请求的残余,例如,依赖于$ _SERVER ['REQUEST_URI']的java eq的脚本没有问题。

You could just drop in a CURL class and write a simple function to do this: 您可以直接插入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);
        }
    }

}

Just dump this in class.CURLHandler.php and you can do this: 只需将其转储到class.CURLHandler.php中即可,您可以这样做:

ofcourse, using $_REQUEST is not really safe (you should check $_SERVER['REQUEST_METHOD']) but you get the point. 当然,使用$ _REQUEST并不是很安全(你应该检查$ _SERVER ['REQUEST_METHOD'])但是你明白了。

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

Ofcourse, CURL's not installed everywhere but we've got native PHP curl emulators for that. 当然,CURL并没有安装到任何地方,但我们有原生的PHP卷曲模拟器。

Also, this gives you even more flexibility than Request.Forward as you could also catch and post-process the output. 此外,这使您比Request.Forward更具灵活性,因为您还可以捕获并后处理输出。

I believe one of the closest analogous methods would be to use the virtual() function on while running php as an apache module. 我相信最接近的类似方法之一是在运行php作为apache模块时使用virtual()函数。

virtual() is an Apache-specific function which is similar to in mod_include. virtual()是一个特定于Apache的函数,类似于mod_include。 It performs an Apache sub-request. 它执行Apache子请求。

If you use an MVC like the Zend Framework provides you can change the controller action or even jump between controller actions. 如果您使用像Zend Framework一样的MVC,您可以更改控制器操作,甚至可以在控制器操作之间跳转。 The method is _forward as described here . 所述方法作为_forward 这里所描述

Try this. 试试这个。

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

on included page the $vars variable will work as the java request attributes 在包含的页面上, $vars变量将作为java请求属性

Concepts Redirect and Forward like in Java, can be achievable in PHP too. 像Java一样的概念重定向和转发也可以在PHP中实现。

Redirect :: header("Location: redirect.php"); Redirect :: header("Location: redirect.php"); -- (URL in address bar changes) - (地址栏中的URL更改)

Forward :: include forward.php ; Forward :: include forward.php ; -- (URL unchanged at address bar) - (地址栏处的URL不变)

Its manageable with this & other programming logics 它可以通过这个和其他编程逻辑进行管理

If you are concerned about CURL availability then you could use file_get_contents() and streams. 如果您担心CURL可用性,那么您可以使用file_get_contents()和流。 Setting up a function like: 设置如下功能:

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;
}

This just sets up a GET, but you can do a post with file_get_contents() as well. 这只是设置一个GET,但你也可以用file_get_contents()做一个帖子。

You can use like: 您可以使用:

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

The exit is need just in case some HTML output was sent before, the header() will not work, so you must sent new header before any output to the browser. 如果之前发送了一些HTML输出,则需要退出,header()将不起作用,因此您必须在向浏览器输出任何内容之前发送新标头。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM