Executing PHP function from JSON - php

I am trying some things with JSON and PHP and there is something that I can't find a way to do, though I'm not 100% sure there is one. But because it looks like a nice option (If possible) I decided to ask here.
I have these examples from jquery offical site. There are two files, the first one is index.php where I execute my Ajax, hete it is:
<!DOCTYPE html>
<html>
<head>
<title>Simple form sending and receiving a JSON object to/from PHP</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var data =
{
"sales": [
{ "firstname" : "John", "lastname" : "Brown" },
{ "firstname" : "Marc", "lastname" : "Johnson" }
] // end of sales array
}
var dataString = JSON.stringify(data);
$.post('simpleformSubmi.php', { data: dataString}, showResult, "text");
});
function showResult(res)
{
$("#fullresponse").html("Full response: " +res);
}
</script>
<div id="fullresponse"></div>
</head>
<body>
Nothing complicated at all. And I have my simpleformSubmi.php which is :
<?php
$logFile = 'logFile';
$res = json_decode(stripslashes($_POST['data']), true);
error_log("result: ".$_POST['data'].", res=".json_encode($res), 3, $logFile);
error_log("\n", 3, $logFile);
//header("Content-type: text/plain");
foreach ($res as $key=>$value)
{
$str[] = $value;
}
$functionArray ="function(){ \$a = 10; echo \$a;}";
$jsStr = $str[0][1];
echo json_encode($jsStr['firstname']);
echo '<hr />';
echo json_encode($res);
echo '<hr />';
echo json_encode($functionArray);
?>
As you can see $functionArray - is in fact a string containing PHP function which I want to return back using JSON and to execute it after that. So is there any way to do that really? Now what I get in index.php afet executing the files is:
"function(){ $a = 10; echo $a;}"
Thanks
Lern

Seems like you're trying to execute a PHP function through JavaScript. Since PHP is executed server-side the only way you have to execute a PHP function in that context is to ask the server back to execute the function for you, by doing another ajax call for example.
Something like this:
index.php
$(document).ready(function(){
var data =
{
"sales": [
{ "firstname" : "John", "lastname" : "Brown" },
{ "firstname" : "Marc", "lastname" : "Johnson" }
] // end of sales array
}
var dataString = JSON.stringify(data);
//Change post() success callback function to executePHP()
$.post('simpleformSubmi.php', { data: dataString}, executePHP, "text");
//Let's define executePHP() outside post() call for clarity
function executePHP()
{
//Ask the server to execute function foo(), and get the result
$.get("example.com/somefile.php?function=foo", function(data)
{
//Success function, do whatever you want.
alert(data);
});
}
});
Then, in somefile.php
<?php
//Condition(s), if any. You could even implement this interface using REST.
//Get function to execute
if($_GET["function"] == "foo")
{
//Output function's result.
echo foo();
}
//The function you want to run
function foo()
{
//Do something
$a = 10;
return $a;
}
?>
If all went well, when JavaScript reaches the alert(data); statement you will see 10.

You cannot execute a PHP function after sending it as a response since the response is received on the client end, and PHP is a server side language.
Usually, you would just return the values. In your example, you would just return an associative array that holds the key value pair a,10.
You can return javascript functions from the PHP script and execute that on the client side using eval but eval'ing opens a pandora's box of security vulnerabilities.

You can't execute PHP code outside of a PHP server. So you can't run it in the browser.
You can, however, pass a string of JavaScript and run it through eval. Some people will tell you that's bad, but remember that eval used to be the only way to parse JSON in the first place.

In order to send back something to PHP, you must call the serverside via, p.e via GET or POST actions from a form. But, no, you cannot execute anything serverside via echo, as echo outputs to the client side. You could always use eval (http://php.net/manual/es/function.eval.php) at serverside to execute something from a POST message, but it is not recommended as it can open a great security hole.

You've returned a function (I'm assuming you meant this to be javascript), now you need to call it. This can be done by using the jQuery $.post success callback.
Try changing this..
$.post('simpleformSubmi.php', { data: dataString}, showResult, "text");
To
$.post('simpleformSubmi.php', { data: dataString}, function(data){eval(data)}, "text");
If its PHP (which it looks like) and not Javascript, then this will need to executed from the server. Being that its a server-side language 'n all.

Related

send data via ajax to xml type php [duplicate]

This may be a simple answer, but I'm using jQuery's $.ajax to call a PHP script. What I want to do is basically put that PHP script inside a function and call the PHP function from javascript.
<?php
if(isset($_POST['something'] {
//do something
}
?>
to this
<?php
function test() {
if(isset($_POST['something'] {
//do something.
}
}
?>
How would i call that function in javascript? Right now i'm just using $.ajax with the PHP file listed.
Use $.ajax to call a server context (or URL, or whatever) to invoke a particular 'action'. What you want is something like:
$.ajax({ url: '/my/site',
data: {action: 'test'},
type: 'post',
success: function(output) {
alert(output);
}
});
On the server side, the action POST parameter should be read and the corresponding value should point to the method to invoke, e.g.:
if(isset($_POST['action']) && !empty($_POST['action'])) {
$action = $_POST['action'];
switch($action) {
case 'test' : test();break;
case 'blah' : blah();break;
// ...etc...
}
}
I believe that's a simple incarnation of the Command pattern.
I developed a jQuery plugin that allows you to call any core PHP function or even user defined PHP functions as methods of the plugin: jquery.php
After including jquery and jquery.php in the head of our document and placing request_handler.php on our server we would start using the plugin in the manner described below.
For ease of use reference the function in a simple manner:
var P = $.fn.php;
Then initialize the plugin:
P('init',
{
// The path to our function request handler is absolutely required
'path': 'http://www.YourDomain.com/jqueryphp/request_handler.php',
// Synchronous requests are required for method chaining functionality
'async': false,
// List any user defined functions in the manner prescribed here
// There must be user defined functions with these same names in your PHP
'userFunctions': {
languageFunctions: 'someFunc1 someFunc2'
}
});
And now some usage scenarios:
// Suspend callback mode so we don't work with the DOM
P.callback(false);
// Both .end() and .data return data to variables
var strLenA = P.strlen('some string').end();
var strLenB = P.strlen('another string').end();
var totalStrLen = strLenA + strLenB;
console.log( totalStrLen ); // 25
// .data Returns data in an array
var data1 = P.crypt("Some Crypt String").data();
console.log( data1 ); // ["$1$Tk1b01rk$shTKSqDslatUSRV3WdlnI/"]
Demonstrating PHP function chaining:
var data1 = P.strtoupper("u,p,p,e,r,c,a,s,e").strstr([], "C,A,S,E").explode(",", [], 2).data();
var data2 = P.strtoupper("u,p,p,e,r,c,a,s,e").strstr([], "C,A,S,E").explode(",", [], 2).end();
console.log( data1, data2 );
Demonstrating sending a JSON block of PHP pseudo-code:
var data1 =
P.block({
$str: "Let's use PHP's file_get_contents()!",
$opts:
[
{
http: {
method: "GET",
header: "Accept-language: en\r\n" +
"Cookie: foo=bar\r\n"
}
}
],
$context:
{
stream_context_create: ['$opts']
},
$contents:
{
file_get_contents: ['http://www.github.com/', false, '$context']
},
$html:
{
htmlentities: ['$contents']
}
}).data();
console.log( data1 );
The backend configuration provides a whitelist so you can restrict which functions can be called. There are a few other patterns for working with PHP described by the plugin as well.
I would stick with normal approach to call the file directly, but if you really want to call a function, have a look at JSON-RPC (JSON Remote Procedure Call).
You basically send a JSON string in a specific format to the server, e.g.
{ "method": "echo", "params": ["Hello JSON-RPC"], "id": 1}
which includes the function to call and the parameters of that function.
Of course the server has to know how to handle such requests.
Here is jQuery plugin for JSON-RPC and e.g. the Zend JSON Server as server implementation in PHP.
This might be overkill for a small project or less functions. Easiest way would be karim's answer. On the other hand, JSON-RPC is a standard.
You can't call a PHP function with Javascript, in the same way you can't call arbitrary PHP functions when you load a page (just think of the security implications).
If you need to wrap your code in a function for whatever reason, why don't you either put a function call under the function definition, eg:
function test() {
// function code
}
test();
Or, use a PHP include:
include 'functions.php'; // functions.php has the test function
test();
You are going to have to expose and endpoint (URL) in your system which will accept the POST request from the ajax call in jQuery.
Then, when processing that url from PHP, you would call your function and return the result in the appropriate format (JSON most likely, or XML if you prefer).
You may use my library that does that automatically, I've been improving it for the past 2 years http://phery-php-ajax.net
Phery::instance()->set(array(
'phpfunction' => function($data){
/* Do your thing */
return PheryResponse::factory(); // do your dom manipulation, return JSON, etc
}
))->process();
The javascript would be simple as
phery.remote('phpfunction');
You can pass all the dynamic javascript part to the server, with a query builder like chainable interface, and you may pass any type of data back to the PHP. For example, some functions that would take too much space in the javascript side, could be called in the server using this (in this example, mcrypt, that in javascript would be almost impossible to accomplish):
function mcrypt(variable, content, key){
phery.remote('mcrypt_encrypt', {'var': variable, 'content': content, 'key':key || false});
}
//would use it like (you may keep the key on the server, safer, unless it's encrypted for the user)
window.variable = '';
mcrypt('variable', 'This must be encoded and put inside variable', 'my key');
and in the server
Phery::instance()->set(array(
'mcrypt_encrypt' => function($data){
$r = new PheryResponse;
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $data['key'] ? : 'my key', $data['content'], MCRYPT_MODE_ECB, $iv);
return $r->set_var($data['variable'], $encrypted);
// or call a callback with the data, $r->call($data['callback'], $encrypted);
}
))->process();
Now the variable will have the encrypted data.

$.getJSON not working with simple PHP Script

The JS doesn't work with the PHP script. I get no response.
Here's the PHP script:
<?php
$a = array('data' => 'Hello');
echo json_encode($a);
?>
Here is the JQuery Script:
function getCityAndState(data, location)
{
var jsonString = {"zipCode": data};
var outR = outputResults
alert("JSON String:" + jsonString.zipCode);
if (location === "living")
{
$("#livingCityField").val("");
$("#livingStateField").val("");
alert("Inside getCityAndState: " + location);
//$.get("testfile.php",
// {zipCode: data},
// outR,
// 'text'
// );
$.getJSON("testfile.php",function(d) {
alert("JSON Data: " + d.data);
});
}
What am I doing wrong?
alert("Inside getCityAndState: " + location); does execute as expected but otherwise nothing happens. There is no exception thrown, no error message, nothing. It doesn't return any data at all.
I'm using Aptana 2 as an IDE, in case that makes a difference.
Your PHP script is missing the Header, it should be something like:
<?php
header('Content-type: text/json'); //added line
$a = array('data' => 'Hello');
echo json_encode($a);
?>
The second parameter of jQuery's $.getJSON() function isn't the callback that returns the data, it is supposed to be a map or string containing additional data to be sent to the server. The callback function is the third parameter.
I didn't test this, but it should be something along these lines:
$.getJSON('ajax/test.json', "", function(data, textStatus, jqXHR){
//In here you should have access to the data return by the server thourgh the "data" variable.
});
EDIT: As very well pointed out by #Rocket and #Tadeck, optional arguments can be omitted and "rearranged" since jQuery checks the argument's type. This is the case with the second and third arguments of the getJSON() function.
Given that, and although this shouldn't be the source of the problem, it makes sure the function receives all the arguments in the expected order, and it should yield the same result as omitting the second parameter.
Documentation: http://api.jquery.com/jQuery.getJSON/

My return functions isn't working with my jQuery ajax

I have this:
$("#upvote").click(function(){
var up = parseInt(document.getElementById('voteScore').innerHTML);
up++;
document.getElementById('voteScore').innerHTML = up;
$.ajax({
type: 'POST',
url: 'include/mysql_lib.php',
data: {'data[]':['upvote','<?php echo $id; ?>', '<?php echo $uid; ?>']},
dataType: "text",
success: function(dataType) {
if (dataType == "false") {
var up = parseInt(document.getElementById('voteScore').innerHTML);
up--;
document.getElementById('voteScore').innerHTML = up;
}
}
});
});
The mysql_lib.php file (if an error is found) has a line like this:
return "false";
What am I doing wrong? I've never used jQuery before.
The AJAX function's server response (the 'dataType' variable in your code) stores whatever your PHP script wrote-out to the server. In your PHP script if you return "false" that will return a string from a function, but if you want to pickup the value in your JavaScript you should use echo "false" so that the JavaScript's response from the server will be false.
function test() {
//do some work
return "false";
}
echo test();//this will output "false" to the browser
function test() {
echo "false";//this will output "false" to the browser
}
When running into issues like this it is a good idea to put a console.log(dataType) or alert(dataType) inside your AJAX callback function to see what is being output by your PHP. The response from your PHP script can also be viewed in most developer tools (like FireBug).
And a suggestion for ya. If you want to get into outputting more complex information from your PHP script, take a look at the PHP json_encode() function which makes communicating between PHP and JavaScript painless.

jQuery ajax call errors with sendToValue is not defined, what is wrong with this jquery code ?

I'm kind of new to jquery/ajax calls, I have this code below to pull from php page json values.
$(function(){
$('#search').keyup(function() {
sendValue($(this).val);
});
});
function sendValue(str)
{
$.post(
"back/search.php",
{ sendToValue: str },
function(data) {
if(!data.empty){
//Put the result in the suggest div
$("#suggest").html(data.returnedFromValue);
}
},"json"
);
}
and here is the search.php file
$values = $database->get_by_name($_POST['sendToValue']);
if( !$values ) {
echo json_encode(array("returnedFromValue" => "ERROR"));
}
else
{
foreach($values as $value) {
echo json_encode(array("returnedFromValue" => $value));
}
}
The problem that that the value doesn't appear in the suggest div, the only output there is "error", when I check the ajax request in firebug under post section it gives me the message that sendToValue is not defined any ideas? Thanks!
The first thing that leaps out at me (there may be other problems, but this is the one I noticed first) is that you're missing the parentheses after val in the call to sendValue:
sendValue($(this).val);
should be:
sendValue($(this).val());
Currently, you're passing the val method itself into the sendValue function, rather than the result of calling that method.
$(this).valprobably needs to be $(this).val()
When programming JavaScript Firebug and console.log()are your friends.

using jquery $.ajax to call a PHP function

This may be a simple answer, but I'm using jQuery's $.ajax to call a PHP script. What I want to do is basically put that PHP script inside a function and call the PHP function from javascript.
<?php
if(isset($_POST['something'] {
//do something
}
?>
to this
<?php
function test() {
if(isset($_POST['something'] {
//do something.
}
}
?>
How would i call that function in javascript? Right now i'm just using $.ajax with the PHP file listed.
Use $.ajax to call a server context (or URL, or whatever) to invoke a particular 'action'. What you want is something like:
$.ajax({ url: '/my/site',
data: {action: 'test'},
type: 'post',
success: function(output) {
alert(output);
}
});
On the server side, the action POST parameter should be read and the corresponding value should point to the method to invoke, e.g.:
if(isset($_POST['action']) && !empty($_POST['action'])) {
$action = $_POST['action'];
switch($action) {
case 'test' : test();break;
case 'blah' : blah();break;
// ...etc...
}
}
I believe that's a simple incarnation of the Command pattern.
I developed a jQuery plugin that allows you to call any core PHP function or even user defined PHP functions as methods of the plugin: jquery.php
After including jquery and jquery.php in the head of our document and placing request_handler.php on our server we would start using the plugin in the manner described below.
For ease of use reference the function in a simple manner:
var P = $.fn.php;
Then initialize the plugin:
P('init',
{
// The path to our function request handler is absolutely required
'path': 'http://www.YourDomain.com/jqueryphp/request_handler.php',
// Synchronous requests are required for method chaining functionality
'async': false,
// List any user defined functions in the manner prescribed here
// There must be user defined functions with these same names in your PHP
'userFunctions': {
languageFunctions: 'someFunc1 someFunc2'
}
});
And now some usage scenarios:
// Suspend callback mode so we don't work with the DOM
P.callback(false);
// Both .end() and .data return data to variables
var strLenA = P.strlen('some string').end();
var strLenB = P.strlen('another string').end();
var totalStrLen = strLenA + strLenB;
console.log( totalStrLen ); // 25
// .data Returns data in an array
var data1 = P.crypt("Some Crypt String").data();
console.log( data1 ); // ["$1$Tk1b01rk$shTKSqDslatUSRV3WdlnI/"]
Demonstrating PHP function chaining:
var data1 = P.strtoupper("u,p,p,e,r,c,a,s,e").strstr([], "C,A,S,E").explode(",", [], 2).data();
var data2 = P.strtoupper("u,p,p,e,r,c,a,s,e").strstr([], "C,A,S,E").explode(",", [], 2).end();
console.log( data1, data2 );
Demonstrating sending a JSON block of PHP pseudo-code:
var data1 =
P.block({
$str: "Let's use PHP's file_get_contents()!",
$opts:
[
{
http: {
method: "GET",
header: "Accept-language: en\r\n" +
"Cookie: foo=bar\r\n"
}
}
],
$context:
{
stream_context_create: ['$opts']
},
$contents:
{
file_get_contents: ['http://www.github.com/', false, '$context']
},
$html:
{
htmlentities: ['$contents']
}
}).data();
console.log( data1 );
The backend configuration provides a whitelist so you can restrict which functions can be called. There are a few other patterns for working with PHP described by the plugin as well.
I would stick with normal approach to call the file directly, but if you really want to call a function, have a look at JSON-RPC (JSON Remote Procedure Call).
You basically send a JSON string in a specific format to the server, e.g.
{ "method": "echo", "params": ["Hello JSON-RPC"], "id": 1}
which includes the function to call and the parameters of that function.
Of course the server has to know how to handle such requests.
Here is jQuery plugin for JSON-RPC and e.g. the Zend JSON Server as server implementation in PHP.
This might be overkill for a small project or less functions. Easiest way would be karim's answer. On the other hand, JSON-RPC is a standard.
You can't call a PHP function with Javascript, in the same way you can't call arbitrary PHP functions when you load a page (just think of the security implications).
If you need to wrap your code in a function for whatever reason, why don't you either put a function call under the function definition, eg:
function test() {
// function code
}
test();
Or, use a PHP include:
include 'functions.php'; // functions.php has the test function
test();
You are going to have to expose and endpoint (URL) in your system which will accept the POST request from the ajax call in jQuery.
Then, when processing that url from PHP, you would call your function and return the result in the appropriate format (JSON most likely, or XML if you prefer).
You may use my library that does that automatically, I've been improving it for the past 2 years http://phery-php-ajax.net
Phery::instance()->set(array(
'phpfunction' => function($data){
/* Do your thing */
return PheryResponse::factory(); // do your dom manipulation, return JSON, etc
}
))->process();
The javascript would be simple as
phery.remote('phpfunction');
You can pass all the dynamic javascript part to the server, with a query builder like chainable interface, and you may pass any type of data back to the PHP. For example, some functions that would take too much space in the javascript side, could be called in the server using this (in this example, mcrypt, that in javascript would be almost impossible to accomplish):
function mcrypt(variable, content, key){
phery.remote('mcrypt_encrypt', {'var': variable, 'content': content, 'key':key || false});
}
//would use it like (you may keep the key on the server, safer, unless it's encrypted for the user)
window.variable = '';
mcrypt('variable', 'This must be encoded and put inside variable', 'my key');
and in the server
Phery::instance()->set(array(
'mcrypt_encrypt' => function($data){
$r = new PheryResponse;
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $data['key'] ? : 'my key', $data['content'], MCRYPT_MODE_ECB, $iv);
return $r->set_var($data['variable'], $encrypted);
// or call a callback with the data, $r->call($data['callback'], $encrypted);
}
))->process();
Now the variable will have the encrypted data.

Categories