【问题标题】:Call any PHP function using a Javascript AJAX post request使用 Javascript AJAX 发布请求调用任何 PHP 函数
【发布时间】:2019-08-21 16:20:23
【问题描述】:

我搜索了很多主题,但找不到答案。我的目标是在 PHP 页面上有一个调用 Javascript AJAX 发布请求的 HTML 超链接来运行 PHP 函数(可选地带有任意数量的参数)。许多主题为定义的函数(具有特定名称)解决了这个问题。我想概括一下 AJAX 发布请求函数,以便将 PHP 函数名称传递给 AJAX 请求来调用它,这样我就可以在 Javascript 中定义要调用的 PHP 函数。

这就是我所拥有的,但是在 PHP 脚本中出错了...

HTML:

<a onclick="call_php('php_function_name', ['arg_1', 'arg_2']);">call</a>
<p id="demo"></p>

Javascript:

function call_php(fname, args) {
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function () {
        if (this.readyState == 4 && this.status == 200) {
            document.getElementById('demo').innerHTML = this.responseText;
        }
    };
    xhttp.open('POST', 'includes/functions.php', true);
    xhttp.setRequestHeader('Content-type', 'application/json');
    xhttp.send(JSON.stringify({
        'fname': fname,
        'args': args
    }));
}

在 Javascript 中,我质疑 JSON.stringify()setRequestHeader() 在这种情况下是否正确使用。

PHP,它应该在它的文件中调用一个函数:

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    //header('Content-Type: application/json');
    $post = json_decode($_POST/*, true*/);
    // DO SOMETHING TO CALL: fname(...args);
}
function php_function_name(arg_1, arg_2) {
    // A FUNCTION...
}

在 PHP 中,我质疑 header('Content-Type: application/json'),因为它已经在 J​​avascript 中定义。但主要问题是:如何编写 PHP 代码来调用 PHP 函数?顺便说一句:当我打印 echo $post 时,它会发出警告:json_decode() 期望参数 1 是字符串,给定数组...

【问题讨论】:

  • 您是否正在寻找像 call_user_func or call_user_func_array 这样的 PHP 函数,例如call_user_func_array('php_function_name', array(&amp;$a))?
  • @gus27 所说的,虽然您可能想先检查 JS 尝试调用的函数是否确实存在,但请使用 method_exists()
  • 谢谢,我会看看call_user_func 函数,但是如何将帖子数据变量nameargs 放入该函数中?
  • 只是为了确保清楚:允许调用任何 PHP 函数是一个非常糟糕的主意。考虑一下如果我在您的网站上打开一个 JS 控制台并输入类似 call_php('exec', ['rm -rf /']); 的内容会发生什么。希望您能看到我以这种方式真正弄乱您的系统的可能性是无穷无尽的。也不要尝试将其列入黑名单,将允许的功能列入白名单,对任何其他输入仅以“错误”响应。

标签: javascript php json ajax


【解决方案1】:

PHP 手册states 指出$_POST 超级全局变量仅包含application/x-www-form-urlencodedmultipart/form-data 类型的post 数据的post 参数。

通过 使用 application/x-www-form-urlencoded 时的 HTTP POST 方法或 multipart/form-data 作为请求中的 HTTP Content-Type。

但是,您正在尝试发送正文类型为 application/json 的发布请求。

要在 PHP 中读取原始正文,您可以执行 this:

$postdata = file_get_contents("php://input");

这将为您提供整个请求正文的字符串。然后你可以json_decode这个字符串来获取想要的JSON对象。

至于调用请求中提供的函数的部分,call_user_func_array 可以很好地完成工作。这是否是您应该做的事情是一个完全不同的问题。据我了解,您正在了解router and a controller 的概念。

我已经写了一个简单的 sn-p 我认为你想做的事情:

<?php

switch ($_SERVER['REQUEST_METHOD']) {
  case 'POST':
    post_handler();
    return;
  case 'GET':
    get_handler();
    return;
  default:
    echo 'Not implemented';
    return;
}

function post_handler() {
  $raw_data = file_get_contents("php://input");
  $req_body = json_decode($raw_data, TRUE);
  call_user_func_array($req_body['function'], $req_body['args']);
}

function get_handler() {
  echo 'This page left intentionally blank.';
}

function some_function($arg1, $arg2) {
  echo $arg1.' '.$arg2;
}

?>

【讨论】:

  • 谢谢,它工作得很好!不过,请记住 IMSoP 的评论:允许调用任何 PHP 函数是一个极其危险的安全问题。也不要尝试将允许的功能列入白名单”。但是对于我的安全性不是很重要的小项目,这可以做到。
【解决方案2】:

注释 json_decode 并通过调用 print_r ($_POST) 输出您的 $_POST; 你应该看到你的数据结构,如果它是一个带有数据键和值的简单数组,那么你不必解码它,但如果数组只有一列并且它的值是你的数据,那么就拿它的键并用它来解码内容

【讨论】:

  • 我得到一个有趣的响应,一个空数组:Array ( )。有什么想法哪里出错了?
  • 由于某种原因,您的 ajax 请求未发送任何数据,请尝试将其作为手动解析的普通数据发送,例如“key=value&key2=value2”,看看会发生什么
  • Array ( [key] =&gt; value [key2] =&gt; value2 ) 是的,工作正常!为什么不使用 json 格式? ;p
  • 我不知道我有同样的问题,但使用 angularjs 我使用 JQuery 中的 formData 解决了它
  • 谢谢,我一直在尝试不使用 jQuery ;)
猜你喜欢
  • 1970-01-01
  • 2019-03-02
  • 2012-08-19
  • 1970-01-01
  • 1970-01-01
  • 2013-01-30
  • 1970-01-01
  • 2017-04-16
  • 1970-01-01
相关资源
最近更新 更多