Call different PHP functions from javascript - javascript

I realize that calling database from JavaScript file is not a good way. So I have two files:
client.js
server.php
server.php has multiple functions.
Depending upon a condition, I want to call different functions of server.php.
I know how to call server.php, but how do I call different functions in that file?
My current code looks like this:
function getphp () {
//document.write("test");
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
// data is received. Do whatever.
}
}
xmlhttp.open("GET","server.php?",true);
xmlhttp.send();
};
What I want to do is something like (just pseudo-code. I need actual syntax):
xmlhttp.open("GET","server.php?functionA?params",true);

Well based on that premise you could devise something like this:
On a sample request like this:
xmlhttp.open("GET","server.php?action=save",true);
Then in PHP:
if(isset($_GET['action'])) {
$action = $_GET['action'];
switch($action) {
case 'save':
saveSomething();
break;
case 'get':
getSomething();
break;
default:
// i do not know what that request is, throw an exception, can also be
break;
}
}

Just do something like this, i hope this will work
xmlhttp.open("GET","server.php?function=functioName&paramsA=val1&param2=val2",true);

You will most likely need to create the mechanism yourself.
Say the URL will look like server.php?function=foo&param=value1&param=value2
On the server side you will now have to check whether a function with such a name exists, and if it does, call it with these parameters. Useful links on how to do it are http://php.net/manual/en/function.function-exists.php and http://php.net/manual/en/functions.variable-functions.php
Otherwise, if you don't want to have it like this, you can always go with if/switch and simply check that if $_GET["function"] is something, then call something etc.

You can use jQuery too. Much less code than pure js. I know pure js is faster but jQuery is simpler. In jQuery you can use the $.ajax() to send your request. It takes a json structured array like this:
$.ajax({
url: "example.php",
type: "POST",
data: some_var,
success: do_stuff_if_no_error_occurs(),
error: do_stuff_when_error_occurs()
});

Here's a dynamic way to solve this issue:
xmlhttp.open("GET","server.php?action=save",true);
PHP Code:
<?php
$action = isset($_GET['action']) ? $_GET['action'] : '';
if(!empty($action)){
// Check if it's a function
if(function_exists($action)){
// Get all the other $_GET parameters
$params = array();
if(isset($_GET) && sizeof($_GET) > 1){
foreach($_GET as $key => $value){
if($key != 'action'){
$params[] = $value;
}
}
}
call_user_func($action, $params);
}
}
?>
Keep in mind that you should send the parameters in the same order of function arguments.
Let's say:
xmlhttp.open("GET","server.php?action=save&username=test&password=mypass&product_id=12",true);
<?php
function save($username, $password, $product_id){
...
}
?>
You can't write the API Call that way:
xmlhttp.open("GET","server.php?action=save&password=mypass&username=test&product_id=12",true);
Keep in mind that it's really bad to send "function namespaces" along with the parameters to a back-end. You're exposing your back-end and without proper security measures, your website will be vulnerable against SQL Injection, dictionary attack, brute force attack (because you're not checking a hash or something), and it'll be accessible by almost anyone (you're using GET using of POST and anyone can do a dictionary attack to try to access several functions ... there's no privileges check) etc.
My recommendation is that you should use a stable PHP Framework like Yii Framework, or anything else.
Also avoid using GET when you're sending data to the back-end. Use POST instead.

Related

Different ways to use local variables from HTML / Javascript in PHP

Recently I have been doing a lot of work in PHP and I have become familiar with how it works. I stand by what I have said before; That every problem has an endless amount of solutions. So that is what I am after, solutions that solve the same problem.
In this case, I want variables/references to values from localstorage:
localStorage.setItem("user", "bananaflakes55");
localStorage.getItem("user");
and directly include them in PHP files. Now I have found out that using echo have a variety of uses, for example:
echo '<script type="text/javascript"> window.location.replace("' . $refclinklogin . '"); </script>';
Granted that the value there are on serverside -> client side. In this case I want similar solutions that necessarily wont require me to create a GET or POST, with HTML elements like forms, that connect these.
To sum up, I want solutions that can bring values from local and session storage, to PHP. Bring forth some funky ideas, if possible. From what I have read it is a tricky one.
Even if i understand what you want, process sould be running from PHP to client rather than the reverse.
With this in mind, a light solution can be something like that :
window.addEventListener("load", function() {
let request = new XMLHttpRequest();
request.open("POST", 'localStorageToSession.php', true);
request.onload = function () {
let saveResponse = request.responseText;
// if you want a callback or use some script return
}
let data = "jsonLocalStorage=" + JSON.stringify(window.localStorage);
request.send(data);
}) ;
Once the page is loaded, send all localStorage parsed in json to a PHP treatment (here called localStorageToSession.php).
So you can convert localstorage as $_SESSION. Something like that :
$_SESSION['jsLocalStorage'] = json_decode($_POST['jsonLocalStorage'], true) ;
Then you can use $_SESSION['jsLocalStorage'] in your backend treatments. Don't forget to add session_start() on all your files.
You can save the xml request in a function and call once localStorage is updated).
Even if that solution works, i don't recommand it if you have to deal with safety informations like passwords or user special access.

Getting data in JavaScript from php

Specifically, I need to get data in html from a database. If there is a simple way to do that in JavaScript then just skip the next part ^^
I have successfully written the php code to retrieve the data from the database, which is something like this:
$host = (host)
$user = (user)
$db = (database)
$pw = (password)
$funct = $_GET["Function"];
switch ($funct) {
case "getName": {
$personid=$_GET["PersonID"];
$output = getName($host, $user, $pw, $db, $personid);
echo $output;
break;
}
}
Of course there are more values for $funct, but to keep things short I only wrote one and left out the function itself. I tested it by making a form with method="GET", and it correctly prints the name. So my actual question is how to pass the name onto a html document, where I want to list the names of certain people. I did research and found for example that I need to use "echo $output;", I had originally tried "return $output;" but that was not enough. My current js-code is something like this:
"use strict";
function getName(field_id, person_id) {
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("name"+field_id).innerHTML=this.responseText;
}
};
request.open("GET", "people.php");
request.setRequestHeader("Function", "getName");
request.setRequestHeader("PersonID", person_id);
request.send();
}
I originally tried fetch(), because it was recommended by javascript.info, but I didn't find many examples, so I scratched that. If i change it to ".innerHTML=this.responseText+this.status;" it just prints "200" onto the name field. There are no error messages.
It probably looks like I'm making it too complicated, but the code is supposed to do more stuff than what I shared, I'm just keeping it simple for you to understand.
I hope you can help me!
$_GET won’t give you the request headers, it will give query string parameters. You want to change your request to request.open("GET", "people.php?Function=getName&PersonId=" + person_id).

I'm putting my entire $_SESSION variable into a json object on page load. While this works for me, is this a good practice?

I've been doing something this at the bottom of all my views:
<script type='text/javascript'>
$.post('php/ajax.php', {type:'session'}).done(function(data){
var session = JSON.parse(data);
$(document).ready(function(){
$.getScript('resources/redactor/redactor.js');
$.getScript('javascript/year_long_calendar.js');
$.getScript('javascript/edit_lesson_modal.js');
});
});
</script>
This works really well for me. All my scripts get loaded inside of a single docReady, and all my ajax requires a token that gets generated upon login and stored in $_SESSION. This stops people from hitting my ajax logic using fake headers. By doing this, my ajax calls look something like:
$.post(url:'ajax.php', {token:session.token, id:id}).done(function(data){ ... });
I can also access other session variables
var user_id = session.user_id;
Since I've been doing this from the start of the project, I intentionally keep any sensitive information like passwords out of the session variable. What are your thoughts on this? Does any of this strike you as insecure, or terribly inefficient? I realize $.getScript is often used as a lazy way to load libraries, but I think I've found a pretty valid use for it.
None of the data in $_SESSION is sensitive except the token, and you have to be logged in to get one. Unless someone malicious hops on a machine while the real user is away and knows exactly where my ajax logic is, how it works, how I store my session, and fakes a quick header on PostMan to delete all my tables, I don't see it being an issue.
EDIT:
#AnotherGuy helped me realize a much better solution. My ajax.php file now looks like this:
<?php session_start();
include('connect.php');
include('functions.php');
// check to see if http request is ajax (easy to fake but hey might as well)
if($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'){
// when the user logs in, a random number is generated and saved to $_SESSION['token'].
// this block is used to pass the token to a javascript variable securely
if($_POST['type'] == 'session'){
$session = [
'token'=>$_SESSION['token'],
'user_id'=>$_SESSION['user_id']
];
echo json_encode($session);
}
// all post requests must pass the correct token variable to step into this block and access the ajax logic
if(isset($_POST['token']) && $_POST['token'] == $_SESSION['token']){
if($_POST['type'] == 'get'){
$where = null;
if(isset($_POST['where'])){
$where = json_decode($_POST['where']);
}
$order_by = null;
if(isset($_POST['order_by'])){
$order_by = json_decode($_POST['order_by']);
}
echo json_encode(get($_POST['db'], $_POST['table'], $where, $order_by)->fetchAll());
}
if($_POST['type'] == 'put'){
$set = json_decode($_POST['set']);
echo put($_POST['db'], $_POST['table'], $set);
}
if($_POST['type'] == 'update'){
$set = json_decode($_POST['set']);
$where = json_decode($_POST['where']);
update($_POST['db'], $_POST['table'], $set, $where);
}
if($_POST['type'] == 'delete'){
$where = json_decode($_POST['where']);
delete($_POST['db'], $_POST['from'], $where);
}
From how you describe you are using the session I cannot see any harm in it, but I still think it is dangerous. Imagine you in the future work on another project and then come back to this. Will you still remember not to store any sensitive information inside the session? As a basic rule of thumb is to never store sensitive information in the session unless it is the only solution, which it rarely is. But sometimes mistakes are made and they can hurt you!
I would change this to something that looks/works in the same way, but offers you more decoupling from the session. If you are fetching the entire session you are bound to retrieve some information which would never be used or should never be available to client side (through Javascript). I would create a single page that you request which can only provide the necessary information. That way you can also ensure only required information is exposed to the client side.
So instead of requesting a generic ajax.php file, I would create a page called (or something like it) userInfo.php. That way you can also eliminate the type variable you send along with it.
Hope this can help you, happy coding!
You could store that session data in browser with sesssionStorage in a serialized JSON string and manipulate it from there. Many recommend this approach over using cookies W3Schools
Cheers.

AJAX load specified function from php file

I am currently using the script below to fill some divs with data i need
function fillLeagues(){
var load = $.get('drawleague.php');
$(".really").html('Refreshing');
load.error(function() {
console.log("Mlkia kaneis");
$(".really").html('failed to load');
// do something here if request failed
});
load.success(function( res ) {
console.log( "Success" );
$(".really").html(res);
});
load.done(function() {
console.log( "Completed" );
});
}
I was wondering if it was possible to call a certain function in the drawleague.php file that will return the info since i don't wanna use say 10 php files to fill 10 divs for example.
Ajax & PHP are different technologies, which means they can only communicate in certain ways
This means that it doesn't matter if you have 1 or 100 files, if you can call the functions inside the file, you can keep it to one file
I would recommend this:
Params
jquery $.GET parameters passing in the url
You can pass parameters through your $.GET request to your PHP file. This means inside your PHP, you can take these params & determine the output
Because you havn't posted any PHP code, here's what you might be able to use:
<?
switch ($_GET["name"]) {
case "x":
return $image_x;
break;
}
}
?>
I'd suggest you use get parameters in order to achieve this behavior. Pass the function name via Get parameter and call it in your PHP file. Of course you need to create some kind of protection. See below (pretty provisoric).
<?php
$param = $_GET['p'];
$whitelist = [
'func1',
'func2',
'func3'
];
if(!in_array($param, $whitelist))
die("Sorry, no manipulating");
call_user_func($param);
function func1()
{
//Some stuff
}
function func2()
{
//Some stuff
}
function func3()
{
//Some stuff
}
?>
Then pass the param in your JS part:
var load = $.get('drawleague.php?p=func1');

How to write a _REQUEST loop?

Here's what I'm doing now in php
$layout_type = $_REQUEST['layout_type'];
$aside_location = $_REQUEST['aside_location'];
$aside_style = $_REQUEST['aside_style'];
$nav_bg = $_REQUEST['nav_bg'];
$nav_bg_hover = $_REQUEST['nav_bg_hover'];
$nav_text_color = $_REQUEST['nav_text_color'];
There has to be a function that writes it for me with the same name?
Here's my ajax call
function generate_clicked()
{
var formData = $("#form").serialize();
$.ajax({
url : "process.php",
type: "POST",
data : formData,
}).done(function ( data ) {
try{
$('#preview').val(data.css);
}
catch(err)
{
console.log(err);
}
document.getElementById("my_iframe").src = data.live_preview_html_page;
});
}
This should work:
foreach ($_REQUEST as $Key => $Value) {
${$Key} = $Value;
}
However I advise against it from severe security implications. To make it secure, I'd recommend first checking the value against an array (white-listing it):
// Complete yourself...
$ValidValues= array("layout_type", "aside_location");
foreach ($_REQUEST as $Key => $Value) {
if (in_array($Key, $ValidValues)) {
${$Key} = $Value;
}
else {
throw new Exception("Security violation. Requesting non-existing variable " . $Key);
}
}
Although you ought to ask yourself why you need this, since your request makes no sense. Arrays are for storing this kind of data, not many individual variables, and you already have that in your $_REQUEST. So please, see down there in your code if you can just use the data straight forward, or provide some more code/context so we can help you further with your problem.
Current versions of PHP provide the extract() function to do what you want, although it's not advised to use it on $_REQUEST since any user can alter your form client-side and submit unexpected variables to your PHP script.
If you choose to use this function, it's strongly recommended that you use the EXTR_SKIP flag or provide a prefix to prevent existing variables from being unexpectedly altered.
extract($_REQUEST, EXTR_SKIP);
// the EXTR_SKIP flag will prevent variables from being overwritten
// or:
extract($_REQUEST, EXTR_PREFIX_ALL, 'prefix_');
// prepend all your new variable names for safety
That said, the safest way by far is to explicitly set each variable as you're doing now. That way, you know exactly what variables are being set when, and security risks are minimized.

Categories