2017-03-07 83 views
1

我搜索了很多主题,但找不到合适的答案。我的目标是建立一个HYML超链接,它调用一个在PHP页面上运行AJAX post请求的Javascript函数,以运行任意数量参数的PHP函数。很多主题都针对特定功能(使用特定名称)解决了这个问题。我想概括一下AJAX发布请求以使用相同的函数调用所有类型的PHP函数。使用没有jQuery的通用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')因为它在使用Javascript已定义。但主要问题是:如何编写PHP代码来调用PHP函数?顺便说一下:当我打印echo $post它给出了一个警告:json_decode()期望参数1是字符串,给定的数组...

+1

您是否在寻找像[call_user_func或call_user_func_array]一个PHP函数(http://php.net/manual/en /function.call-user-func.php),例如'call_user_func_array('php_function_name',数组(&$ a))'? – gus27

+0

可能的重复[调用PHP函数的名称从JavaScript](http://stackoverflow.com/questions/23039439/call-php-function-by-name-from-javascript) – gus27

+0

什么@ gus27说,虽然你可能想要要检查你的JS试图调用的函数实际上是否先存在,请使用[method_exists()](http://php.net/manual/en/function.method-exists.php)。 – Nukeface

回答

5

PHP手册states$_POST超级全局变量仅包含类型为application/x-www-form-urlencodedmultipart/form-data的发布数据的帖子参数。

的使用应用程序/ x-WWW窗体-urlencoded或 的multipart/form-data的作为请求中的HTTP内容类型当经由 HTTP POST方法传递给当前脚本变量的数组。

但是,您正在尝试发送带有application/json类型主体的发布请求。

要读生体在PHP中,你可以做this

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

这会给你整个请求主体的字符串。然后您可以使用json_decode这个字符串来获取所需的JSON对象。

至于调用请求中提供的功能的一部分,call_user_func_array将做的工作的罚款。无论这是否是应该做的事情是一个完全独立的问题。据我所知,你正在磨合router and a controller的概念。

我已经writen什么,我想你想要做一个简单的片断:

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

?> 
+0

谢谢,它完美的作品!不过,请记住IMSoP评论道:允许调用任何PHP函数是一个非常危险的安全问题。不要试图和黑名单,要么有一个允许功能的白名单“,但对于我的小型项目来说,安全性并不重要,这可以做到。 –

1

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

+0

我得到一个有趣的响应,一个空数组:Array()'。任何想法哪里出错? –

+1

出于某种原因,您的ajax请求不发送任何数据尝试发送它作为正常的数据解析manuly像这样“key = value&key2 = value2”,看看会发生什么 –

+0

Array([key] => value [key2] => value2) “是的,这工作正常!为什么不使用json格式? ; p –