I have a table inside a form, once a button is clicked a function is called that confirms the contents of the user input (checking to ensure all fields have info). After proceeding through the if statements and no errors are present I want to write the user information to mysql.
I have written the ajax file (see below) and I think my error is how I call the ajax file. Nothing is getting written to the database table and I am not sure what I am doing wrong
<?php
include_once("config.php");
$con = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);
$date = $_POST['tDate'];
$species = $_POST['tSpecies'];
$sqrNum = $_POST['tSqrNum'];
$lat = $_POST['tLat'];
$lng = $_POST['tLng'];
$cond = $_POST['tCond'];
$num = $_POST['tNum'];
$hab = $_POST['tHab'];
$behav = $_POST['tBahav'];
$reg = $_POST['tReg'];
mysqli_query($con, "INSERT INTO species_reported (date, species, square_num, lat, long, condition, numbers_obs, habitat, behavior, region)
VALUES ('{$date}', '{$species}', '{$sqrNum}', '{$lat}', '{$lng}', '{$cond}', '{$hab}', '{$behav}', '{$reg}')");
?>
and from within the script
else{
//$(document).ready(function(){
$.ajax({
type: "POST",
url:"ajax_write.php",
data:"date=" + tDate +"&Species="+ tSpecies +"&SqrNum="+ tSqrNum +"&lat=" + tLat + "&lng=" + tLng + "&cond=" + tCond +"&num=" + tNum + "&hab=" + tHab + "&behav=" + tBahav + "®=" + tReg,
dataType: "dataString",
cache: "true",
success: function(msg,string,jqXHR){
$("#results").html(msg+string+jqXHR);
}
});
}
}
EDIT... I checked my php log and am seeing Undefined index: tSpecies (as well as all other Post['thisHere']. If this is any help to resolving the issue. My understanding was that I could send the data as I have and ajax would allocate contents to the variables in the php file (ie. from jscript.."date=" tDate would get sent to the xjax file and assign the value of tDate (from javascript) to the php variable $date.
The indexes you use in $_POST have to match the parameter names in the $.ajax data: parameter. You have date=, Species=, etc. in the parameter, but you're trying to access $_POST['tDate'], $_POST['tSpecies'], etc. You need to change one of them to match the other.
Also, I recommend you use an object rather than a string as the data: parameter. The values need to be URL-encoded if they contain special characters, and you're not doing that. If you use an object, jQuery takes care of formatting and encoding it for you. So it should be:
data: { tDate: tDate, tSpecies: tSpecies, tSqrNum: tSqrNum, ... },
BTW, EcmaScript6 provides a shorthand for objects where the property names are the same as the variables containing their values:
data: { tdate, tSpecies, tSqrNum, ... },
Related
I have an HTML form field $_POST["url"], having some URL strings as the value.
Example values are:
https://example.com/test/1234?email=xyz#test.com
https://example.com/test/1234?basic=2&email=xyz2#test.com
https://example.com/test/1234?email=xyz3#test.com
https://example.com/test/1234?email=xyz4#test.com&testin=123
https://example.com/test/the-page-here/1234?someurl=key&email=xyz5#test.com
etc.
How can I get only the email parameter from these URLs/values?
Please note that I am not getting these strings from the browser address bar.
You can use the parse_url() and parse_str() for that.
$parts = parse_url($url);
parse_str($parts['query'], $query);
echo $query['email'];
If you want to get the $url dynamically with PHP, take a look at this question:
Get the full URL in PHP
All the parameters after ? can be accessed using $_GET array. So,
echo $_GET['email'];
will extract the emails from urls.
Use the parse_url() and parse_str() methods. parse_url() will parse a URL string into an associative array of its parts. Since you only want a single part of the URL, you can use a shortcut to return a string value with just the part you want. Next, parse_str() will create variables for each of the parameters in the query string. I don't like polluting the current context, so providing a second parameter puts all the variables into an associative array.
$url = "https://mysite.com/test/1234?email=xyz4#test.com&testin=123";
$query_str = parse_url($url, PHP_URL_QUERY);
parse_str($query_str, $query_params);
print_r($query_params);
//Output: Array ( [email] => xyz4#test.com [testin] => 123 )
As mentioned in another answer, the best solution is using parse_url().
You need to use a combination of parse_url() and parse_str().
The parse_url() parses the URL and return its components that you can get the query string using the query key. Then you should use parse_str() that parses the query string and returns
values into a variable.
$url = "https://example.com/test/1234?basic=2&email=xyz2#test.com";
parse_str(parse_url($url)['query'], $params);
echo $params['email']; // xyz2#test.com
Also you can do this work using regex: preg_match()
You can use preg_match() to get a specific value of the query string from a URL.
preg_match("/&?email=([^&]+)/", $url, $matches);
echo $matches[1]; // xyz2#test.com
preg_replace()
Also you can use preg_replace() to do this work in one line!
$email = preg_replace("/^https?:\/\/.*\?.*email=([^&]+).*$/", "$1", $url);
// xyz2#test.com
Use $_GET['email'] for parameters in URL.
Use $_POST['email'] for posted data to script.
Or use _$REQUEST for both.
Also, as mentioned, you can use parse_url() function that returns all parts of URL. Use a part called 'query' - there you can find your email parameter. More info: http://php.net/manual/en/function.parse-url.php
You can use the below code to get the email address after ? in the URL:
<?php
if (isset($_GET['email'])) {
echo $_GET['email'];
}
I a created function from Ruel's answer.
You can use this:
function get_valueFromStringUrl($url , $parameter_name)
{
$parts = parse_url($url);
if(isset($parts['query']))
{
parse_str($parts['query'], $query);
if(isset($query[$parameter_name]))
{
return $query[$parameter_name];
}
else
{
return null;
}
}
else
{
return null;
}
}
Example:
$url = "https://example.com/test/the-page-here/1234?someurl=key&email=xyz5#test.com";
echo get_valueFromStringUrl($url , "email");
Thanks to #Ruel.
$web_url = 'http://www.writephponline.com?name=shubham&email=singh#gmail.com';
$query = parse_url($web_url, PHP_URL_QUERY);
parse_str($query, $queryArray);
echo "Name: " . $queryArray['name']; // Result: shubham
echo "EMail: " . $queryArray['email']; // Result:singh#gmail.com
A much more secure answer that I'm surprised is not mentioned here yet:
filter_input
So in the case of the question you can use this to get an email value from the URL get parameters:
$email = filter_input( INPUT_GET, 'email', FILTER_SANITIZE_EMAIL );
For other types of variables, you would want to choose a different/appropriate filter such as FILTER_SANITIZE_STRING.
I suppose this answer does more than exactly what the question asks for - getting the raw data from the URL parameter. But this is a one-line shortcut that is the same result as this:
$email = $_GET['email'];
$email = filter_var( $email, FILTER_SANITIZE_EMAIL );
Might as well get into the habit of grabbing variables this way.
$uri = $_SERVER["REQUEST_URI"];
$uriArray = explode('/', $uri);
$page_url = $uriArray[1];
$page_url2 = $uriArray[2];
echo $page_url; <- See the value
This is working great for me using PHP.
In Laravel, I'm using:
private function getValueFromString(string $string, string $key)
{
parse_str(parse_url($string, PHP_URL_QUERY), $result);
return isset($result[$key]) ? $result[$key] : null;
}
A dynamic function which parses string URL and gets the value of the query parameter passed in the URL:
function getParamFromUrl($url, $paramName){
parse_str(parse_url($url, PHP_URL_QUERY), $op); // Fetch query parameters from a string and convert to an associative array
return array_key_exists($paramName, $op) ? $op[$paramName] : "Not Found"; // Check if the key exists in this array
}
Call the function to get a result:
echo getParamFromUrl('https://google.co.in?name=james&surname=bond', 'surname'); // "bond" will be output here
Code that works fine except for the issue of passing a value back and forth between JavaScript, Ajax, and PHP. Using TinyMCE as the editor, when I add a paragraph break in the text, save the data (passing it through JavaScript/Ajax and PHP to do so) the text appears to be okay. Here's the JavaScript and Ajax code -- this works, it passes the data correctly to the PHP program when the submit button is clicked:
// save the main who's who form data:
$("form#who_main").submit(function(e)
{
e.preventDefault();
// first thing, clear out the message div used for this (if there's anything there):
document.getElementById("who_message").innerHTML = "";
// because we're using TinyMCE, need to replace value in that into the textarea
// so that when JavaScript gathers the formData it is getting it from the textarea
// controls (it doesn't know what to do with TinyMCE):
var shortbio = tinymce.get('shortbio').getContent();
document.getElementById( "shortbio" ).value = shortbio;
var user_notes = tinymce.get('user_notes').getContent();
document.getElementById( "user_notes" ).value = user_notes;
var admin_notes = tinymce.get('admin_notes').getContent();
document.getElementById( "admin_notes" ).value = admin_notes;
// this loads all the controls of the form rather than doing one at a time and fumbling
// with the file object ...:
var formData = new FormData(this);
// ajax call to attempt to upload and save the image:
$.ajax
({
type: "POST",
url: "<?php echo $History_html_RootPath; ?>admin/AjaxCalls/who_update_main_save.php",
data: formData,
dataType: "json", // return value is json array
processData : false,
contentType: false,
success: function(data)
{
// need to see if we have an error, if so, display it, otherwise,
// we should hopefully have success ...
if ( data[0].toLowerCase().includes( "error" ) )
{
var errormsg = "<div class='alert alert-danger'>"+data+"</div>";
document.getElementById("who_message").innerHTML = errormsg;
return;
}
else
{
// success!
// update things on screen, so we don't get confused using the data array returned
// from PHP:
document.getElementById("namecode").value = data[0];
document.getElementById("region").value = data[1];
document.getElementById("local").value = data[2];
document.getElementById("preferredtitle").value = data[3];
document.getElementById("shortbio").value = data[4];
tinymce.get('shortbio').setContent( data[4] );
document.getElementById("headshotphoto").value = data[5];
document.getElementById("photographername").value = data[6];
document.getElementById("photographerlink").value = data[7];
document.getElementById("user_notes").value = data[8];
tinymce.get('user_notes').setContent( data[8] );
document.getElementById("admin_notes").value = data[9];
tinymce.get('admin_notes').setContent( data[9] );
// clear out the upload file control:
//document.getElementById("headshotphoto").value = "";
// change the message:
var message = "<div class='alert alert-success'>";
message += "<b>Success!</b> This data has been updated in the <i>holding</i> table.";
message += "</div>";
document.getElementById("who_message").innerHTML = message;
return;
}
} // end success
}); // end ajax call
}) // end of code associated with who_main submit
The PHP file receives the data via post, and I use the PHP function mysqli_real_escape_string() to deal with issues. The one problem with doing this is that it appears to insert backslashes for quotes (single and double), and so on. I just had a thought that might be the cause of the problem, and that is the use of this function, I am not sure. I will test it, but in the meantime. ... I save the data to the table and all is good. If there's a paragraph break, the proper tags are saved out into the table.
<p>Some text</p><p>More text 'quoted text'</p>
When I pass the data back using JSON encoding:
$returndata = array();
$returndata[0] = $namecode;
$returndata[1] = $region;
$returndata[2] = $local;
$returndata[3] = $preferredtitle;
$returndata[4] = $shortbio;
$returndata[5] = $photo_file;
$returndata[6] = $photographername;
$returndata[7] = $photographerlink;
$returndata[8] = $user_notes;
$returndata[9] = $admin_notes;
// done-done:
echo json_encode( $returndata );
return;
The code above (the javascript/Ajax code) comes back looking like:
<p>Some text</p>\r\n<p>More text \'quoted text\'</p>
I need to not have the \r\n and \' (or \") showing up in my text. If I were to save it again like that it gets weirder as the backslashes get duplicated and more. I am sure there's some thing I am missing, but I don't know what it is. This is making me crazy because everything else works exactly as I need it to.
NOTE Added code that I have attempted to use, in PHP, to deal with "escapes", it works for single and double quotes, but not for the \r\n characters -- instead it just strips out the backslash:
function remove_escapes( $string )
{
$string = str_replace ( "\'", "'", $string ); // convert single quote
$string = str_replace ( "\"", """, $string ); // convert double-quote
$string = str_replace ( "\r\n", "", $string ); // remove \r\n
$string = str_replace ( "\\", "", $string ); // remove slash
// anything else giving us heartburn?
return $string;
} // eof: remove_escapes()
If I use this with the json array, I get the letters rn inserted between paragraphs:
$returndata[8] = remove_escapes( $user_notes );
$returndata[9] = remove_escapes( $admin_notes );
maybe doing something like data.replace(/\n/g, '<br>') this will replace all newline markers with the html newline or data.replace(/\\n/g, '<br>') to look for the characters rather than a newline marker
I have done some testing to examine the data and it appears to be happening because of the mysqli_real_escape_string() function when I get the data from the $_POST() array. If I take that out, I am not getting the \r\n codes. So perhaps the jquery post is passing things in a way I don't need that function? Further testing on the three different text controls shows it working without the need to use mysqli_real_escape_string, and I have some extra functionality to deal with looking for JavaScript and such in the text, so I may be able to simplify the code. Unless someone can tell me a reason not to do this ...?
The mysqli_real_escape_string() is there so that special characters are escaped, this helps prevent hacking attacks like sql injection.
It appears that the only solution I can find is to continue with mysqli_real_escape_string(), but when passing the information back, after saving the changes, re-load the data from the table, which does not display the escape characters and therefore avoids the issue. It seems like a lot of extra data processing, but it's only ever (in my code) one row at a time that is being passed back and forth.
I am having issues concatenating two AJAX variables using JQuery and PHP to insert into DB (MySQL)... Here is the code:
$.ajax({
url: DIR+"some.php",
method: "POST",
dataType: "JSON",
data: {
mobile: mobile.val(),
dialcode: dialcode.val();
mobilenumber: mobilenumber.val('dialcode'+'mobile'); // This seems to be the error here
},
The PHP as follows:
<?php
session_start();
if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == "xmlhttprequest") {
if (isset($_POST['username'])) {
$username = preg_replace("#[<> ]#i", "", $_POST['username']);
$mobilenumber = preg_replace("#[^0-9]#i", "", $_POST['dialcode'.'mobile']);
$gender = preg_replace("#[<> ]#i", "", $_POST['gender']);
$country = preg_replace("#[<> ]#i", "", $_POST['country']);
$session = $_SESSION['id'];
$m=$edit->saveEditing( $mobile, $mobilenumber, $gender, $country);
$array = array("msg" => $m);
echo json_encode($array);
}
?>
I am not sure what I am doing wrong here...I am getting :
SyntaxError: Unexpected token ; /locahost/pub/js/file.js:8" please
find the error comment note in the js above to locate the reference
I basically need the dialcode and mobile to be concatenated and inserted as once value into the DB as mobilenumber
The error is on your question:
SyntaxError: Unexpected token ; /locahost/pub/js/file.js:8
This means that, on line 8 of your file.js you have an unexpected ;
6> data: {
7> mobile: mobile.val(),
8> dialcode: dialcode.val(); // Here, you are using ; instead of ,
9> mobilenumber: mobilenumber.val('dialcode'+'mobile'); // Here too!
10> },
JS Object properties should be separated with ,, not with ;.
Also your line where you concatenate two strings is strange, since in jQuery, if you pass any attributes to the val() function, you are SETTING the input value, not reading as you want.
If I understood, you want to merge dialcode and mobile in a single field to send to php, right?
If so, you need to do:
mobilenumber: dialcode.val() + mobile.val(),
Some tips to you that are starting now:
Errors are not monsters, they are your guide, and most of them show directly where your error is. Read them!
Use a GOOD IDE, if you are programming in web, including PHP, I recommend strongly PHPStorm, it's heavy, but will be your best friend forever! S2 That's because a good IDE will highlight all your syntax errors, and have many and many features that you will love as you known them.
I have a couple snippets of code which are working correctly in that they pass the desired result, but they are not working in the way that I would like them to in that I think the code can be improved.
As I will explain more clearly in a minute, my question is on whether I am able to call an element out of a multidimensional array in a different way than I do in the snippet, although the snippet works I just think it is less than ideal.
A jQuery AJAX function:
jQuery("form.everglades_user_submit").submit(function(event){
event.preventDefault();
var user_submit_data = jQuery(".everglades_user_submit").serialize();
jQuery.ajax({
type: "POST",
url: "' . $db_script_location . '",
data: {action: "zip_form", action_data: user_submit_data}
}).done(function(response){
alert("success. response: " + response);
}).fail(function(response){
alert("failure. response: " + response);
});
});
Sends data to a PHP file containing a MySQL query, then passes back a database response to an alert:
if ($_POST["action"] == "zip_form") {
$database_var = mysqli_connect('localhost',/*******************/);
if (!$database_var) {
die( 'Could not connect to database. Error: ' . mysqli_error($database_var) );
} else {
$submitted_zip = $_POST["action_data"];
$modified_data = str_replace("user_zip=","", $submitted_zip);
echo "submitted: " . $submitted_zip . ". Modified : " . $modified_data;
$query = "SELECT * FROM cust_db_fl_sen WHERE rep_zip = '" . $modified_data . "'";
$mysqli_result = mysqli_query($database_var, $query);
while($query_result = mysqli_fetch_array($mysqli_result)) {
echo 'Query result, only rep district atm: ' . $query_result['rep_dist'];
}
exit;
}
As you can see, what I have done is to take the submitted data and remove the part I do not want using str_replace(). I would strongly prefer if I could simply call $modified_data in this way, but it returns an illegal string offset error on 'user_zip,' whether I drop the quotes or not:
$modified_data = $_POST["action_data"]["user_zip"];
However, if I replace the user_zip string with a number such as 0 or 1 it returns a letter (u or s, and so on), so it seems to process user_zip=12345 as a literal string rather than the key->value pair I want it to be processed as.
If I were to evaluate the following in response to an AJAX request based on submission of 11111 in the form text field:
echo $_POST["action_data"];
It would result with "user_zip=11111." user_zip is the key for which 11111 would be the value, however I am only interested in the number because this is used to look up the elected representative for the district of the zip code based on a database query.
To summarize: Is the literal string processing approach with str_replace() standard, or is there a simple way to tell the code that we are dealing with a key->value pair, or an array, or so on, so that I can easily extract with my preferred call method or something similar?
you should first check the content coming from client, use
print_r($_POST["action_data"]);
check whether it contains user_zip=1234 or you can use explode function of php in your else part
else {
$submitted_zip = explode("=",$_POST["action_data"]);
$modified_data = submitted_zip[1];
echo "submitted: " . $submitted_zip . ". Modified : " . $modified_data;
$query = "SELECT * FROM cust_db_fl_sen WHERE rep_zip = '" . $modified_data . "'";
$mysqli_result = mysqli_query($database_var, $query);
while($query_result = mysqli_fetch_array($mysqli_result)) {
echo 'Query result, only rep district atm: ' . $query_result['rep_dist'];
}
exit;
I know there are existing some Questions about Chunking a mysql array in php, but my problem is, that I want to keep the output in JSON.
Scenario:
I want to get data from mysql, do some stuff with it ( like time formatting ) and output it in JSON.
The JSON data is parsed in the browser and visualized over a javascript chart.
Problem:
All of the above is working, but because of the huge amount of data, I'm getting an out of memory error, when I select bigger date ranges to output.
The Idea of directly sending out each x-lines of data is not working because of the JSON format it needs to be. Several JSON chunks won't work, it needs to be one for the chart.
So in the end I need to chunk the data but keep it as one big JSON.
(And setting up the memory limit is not really a solution.)
Ideas:
One Idea would be, to let the browser chunk the date range and ask the data as chunks & then put them together.
Of course this would work, but if there is a way to do this server side, it would be better.
Code:
private function getDB($date1, $date2){
$query = 'SELECT * FROM `db1`.`'.$table.'` WHERE `date` BETWEEN "'.$date1.'" AND "'.$date2.'" order by `date`;';
// date = datetime !
$result = $this->db->query($query);
$array = array();
while ( $row = $result->fetch_assoc () ) {
$array[] = array( strtotime($row[ 'date' ])*1000 , (float)$row[ 'var' ] );
// the formatting needs to be done, so the chart accepts it..
}
$result->close();
return json_encode($array);
}
Since this is not an option,
ini_set("memory_limit","32M")
perhaps you can add LIMIT to the function paramaters and query:
private function getDB($date1, $date2, $start, $pageSize){
$query = 'SELECT * FROM `db1`.`'.$table.'` WHERE `date` BETWEEN "'.$date1.'" AND "'.$date2.'" order by `date` LIMIT $start, $pageSize;';
// date = datetime !
$result = $this->db->query($query);
$array = array();
while ( $row = $result->fetch_assoc () ) {
$array[] = array( strtotime($row[ 'date' ])*1000 , (float)$row[ 'var' ] );
// the formatting needs to be done, so the chart accepts it..
}
$result->close();
return json_encode($array);
}
Then setup a for loop in javascript, call this with Ajax, incrementing the $start variable each time.
Store each responseText.substr(1).substr(-1) in an array.
When the responseText is "", all of the records have been returned.
.join the array with a comma, then add a new opening and closing "{ }", and you should have a JSON equivalent to all records.
Minimal parsing, and you'll be using built-in functions for most of it.
var startRec=0;
var pageSize=50;
var xmlhttp=new XMLHttpRequest();
var aryJSON=[];
var JSON;
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200){
if(xmlhttp.responseText==""){ //Might need to check for "{}" here instead of ""
//All records are received
JSON="{" + aryJSON.join(",") + "}";
aryJSON=[];
startRec=0
}else{
aryJSON.push(xmlhttp.responseText.substr(1).substr(-1));
startRec+=pageSize;
getNextPage();
}
}
}
function getNextPage(){
xmlhttp.open("GET","your.php?start=" + startRec + "&pageSize=" + pageSize,true);
xmlhttp.send();
}
I would recommend that you have the server send the browser exactly what it needs to create the table. Parsing can be a heavy task, so why have the client do that lifting?
I would have your backend send the browser some kind of data structure that represents the table (i.e. list of lists), with all the formatting already done. Rendering the table should be faster and less memory-intensive.
One way of answer would be, to do the chunking on the server, by giving out the JSON, removing the leading [ & ].
#apache_setenv('no-gzip', 1);
#ini_set('zlib.output_compression', 0);
#ini_set('implicit_flush', 1);
$array = array();
echo '[';
$started = false;
while ( $row = $result->fetch_assoc () ) {
$array[] = [ strtotime($row[ 'datetime' ])*1000 , (float)$row[ 'var' ] ];
if(sizeof($array) == 1000){
if($started){
echo ',';
}else{
$started = true;
}
echo substr(substr(json_encode($array),1), 0, -1);
// converting [[datetime1, value1],[datetime2, value2]]
// to [datetime1, value1],[datetime2, value2]
ob_flush();
$array = array();
}
}
if($started)echo ',';
$this->flushJSON($array);
echo ']';
flush();
$result->close();
This is working and reducing the ram usage to 40%.
Still it seems that Apache is buffering something, so the ram usage increases over the time, the script is running. (Yeah, the flush is working, I debugged that, that's not the problem.)
But because of the remaining increase, the fastest way to achieve a clean chunking is to do this like alfadog67 pointed it out.
Also, to mention it, I had to disable the output compression, otherwise apache wouldn't flush it directly..