PHP json_encode losing my UTF-8 escapes? - php

I have an array with strings with international characters.
When I save this in the database I loose the backslashes? Why?
$descr_arr = array("héééllo","world");
$js_encoded = json_encode($descr_arr);
print $js_encoded; // "[\"h\u00e9\u00e9\u00e9llo\",\"world\"]"
$sql_query = "UPDATE test_table SET description = '$js_encoded' WHERE id = 0";
$sql_res = mysql_query($sql_query);
// in the description field in the database I find:
// ["hu00e9u00e9u00e9llo","world"]

You didn't escape your database inputs. Always escape!
Here's one way
$sql_query = "UPDATE test_table SET description = '".
mysql_real_escape_string($js_encoded).
"' WHERE id = 0";
Better yet, use a database wrapper like PDO or ADODb, which would take care of the escaping for you. It would look something like this:
$db->Execute("UPDATE test_table SET description =? where id=?",
array($js_encoded, $id));

Related

PHP code does not recognize some values

EDIT: Thank you all for the very quick answers! I have been at this for a while, trying to figure out why $id was being recognized and why the strings weren't. I feel a bit silly now seeing the obvious answer but I'm relieved to have it working.
I apologize if this has been answered before, I've looked for hours and could not find something similar to help me figure this out.
I am trying to update a row in my database of devices with new information. Problem is, the php file only recognizes $data->devID; and nothing else.
If I have something like
$sql = "UPDATE devices SET devName = 'static test string', description = 'static test string' WHERE devID = $id";
the entry with the correct ID will update in my database table just fine.
If I try
$sql = "UPDATE devices SET devName = $name, description = $desc WHERE devID = $id";
it does not work.
Where am I going wrong?
HTML:
<div data-ng-repeat="info in deviceInfo">
<form class="deviceInfo">
<h2>Device ID: {{info.devID}}</h2>
<p>Device Name:</p>
<input type="text" data-ng-model="info.devName">
<p>Device Description:</p>
<textarea data-ng-model="info.description"></textarea>
<p>Device Available: {{info.isAvailable}}</p>
<input type="submit" name="Update" value="Update" data-ng-click="updateInfo(info.devID, info.devName, info.description)">
</form>
</div>
updateDeviceInfo.php:
<?php
$data = json_decode(file_get_contents("php://input"));
include('config.php');
$id = $data->devID;
$name = $data->devName;
$desc = $data->description;
$sql = "UPDATE devices SET devName = $name, description = $desc WHERE devID = $id";
$qry = $conn->query($sql);
$data = $qry;
$sql = "SELECT * FROM devices";
$qry = $conn->query($sql);
$data = array();
if($qry->num_rows > 0){
while($row = $qry->fetch_object()){
$data[] = $row;
}
}else {
$data[] = null;
}
$conn->close();
echo json_encode($data);
controller.js:
$scope.updateInfo = function($paramID, $paramName, $paramDesc){
console.log($paramID);
console.log($paramName);
console.log($paramDesc);
$scope.dataOneTest = {
devID: $paramID,
devName: $paramName,
description: $paramDesc
};
console.log($scope.dataOneTest.devID);
$http.post('./js/updateDeviceInfo.php', {'devID': $paramID, 'devName': $paramName, 'description': $paramDesc})
.success(function(data){
$scope.results = data;
})
.error(function(err){
$log.error(err);
})
}
tl;dr You are almost certainly performing SQL injection on yourself both by inserting variables directly into a query and by failing to use proper quotation marks around them.
You need to use prepared statements, rather than concatenating variables directly into your query. If, for example, $data->devName contained something nefarious like NULL --, that would toast your entire table. And that's a very mild example of how badly things could go. Prepared statements would render that example (and pretty much all other examples) harmless.
Short-Term Fix
As a short-term fix, put quotation marks in the query and escape your data, like this:
$id = your_database_escape_function($data->devID);
$name = your_database_escape_function($data->devName);
$desc = your_database_escape_function($data->description);
$sql = "UPDATE devices SET devName = '$name', description = '$desc' WHERE devID = $id";
substituting your database's corresponding escaping function for your_database_escape_function(). For example, use $conn->real_escape_string() if $conn is a MySQLi object. See the manual.
The Real Fix
Here's how you really do it correctly, and the solution you should implement ASAP. That is, do this before you go any further if at all possible. Use prepared statements.
Read this entire Q&A and this cheat sheet from OWASP (no affiliation) for more information.
change this becuase description and devName which are string should be quoted
$sql = "UPDATE devices SET devName = $name, description = $desc WHERE devID = $id";
to
$sql = "UPDATE devices SET devName = '".$name."', description = '".$desc."' WHERE devID = $id";
Try this, $sql = "UPDATE devices SET devName = '$name', description = '$desc' WHERE devID = $id";
As title and description are string it requires single quote wrapping inside double quotes.

Php update function

I wrote this code
if(isset($_POST['update'])) {
$webname = $_POST['webname'];
$webmeta = $_POST['webmeta'];
$webdesc = $_POST['webdesc'];
$sql=("UPDATE settings (name, meta, description) VALUES ('$webname', '$webmeta', '$webdesc')");
}
but the problem is that it doesn't update my database, and I cannot find anything wrong in the code ...
I have name "update" on submit button, and all my fields are the same as in code
That's insert! Not update!
$sql=("UPDATE `settings` SET `name` = '$webname',
`meta` = '$webmeta',
`description` = '$webdesc')
WHERE [some condition]");
And replace the [some condition] with a valid condition.
Your code is heavily vulnerable to SQL Injection.
Consider escaping the input by replacing these:
$webname = $_POST['webname'];
$webmeta = $_POST['webmeta'];
$webdesc = $_POST['webdesc'];
With:
$webname = mysql_real_escape_string($_POST['webname']);
$webmeta = mysql_real_escape_string($_POST['webmeta']);
$webdesc = mysql_real_escape_string($_POST['webdesc']);
Or something equivalent like PDO or MySQLi.
mysql_select_db("my_db", $con);
mysql_query("UPDATE Persons SET Age=36
WHERE FirstName='Peter' AND LastName='Griffin'");
u need to first formulate query ans then run/ execute that
$query = "UPDATE table_name
SET column1=value, column2=value2,...
WHERE some_column=some_value";
// Perform Query
$result = mysql_query($query);
You need to run
$connection = mysql_connect($server, $serv_Username, $serv_Password);
mysql_select_db($dbase_name, $connection);
mysql_query($update_query, $connection));
I don't know if this is your problem (don't know how much you know about PHP so just saying).
Also your syntax is wrong. Should be:
UPDATE tablename SET column_name='some_value' WHERE column_name ='some_value'
note that this is diffrent from mentioned above without the thingys covering the column_name parameters.
better is to use PDO as mentioned above, mysql_ can be used "safely" on < PHP 5.5.
Try The code shown below
Just replace the field names and values with your information on your database
$editid=$_POST['editid'];
$username=callback($_POST['username']);
$password=callback($_POST['password']);
$name=callback($_POST['name']);
$age=callback($_POST['age']);
$phone=callback($_POST['phone']);
$emailaddress=callback($_POST['emailaddress']);
$gender=callback($_POST['gender']);
$description=callback($_POST['description']);
$update=update("users","username='".$username."',password='".$password."',name='".$name."',age='".$age."',phone='".$phone."',emailaddress='".$emailaddress."',gender='".$gender."',description='".$description."' ","ID='".$editid."' " );

PHP Query failing, show error?

I have a query on my page that uses a GET variable to pull data from my table...
If I echo my GET var the data is there so im doing something wrong with my query, instead of or die can I show an error in the browser?
// Get USER ID of person
$userID = $_GET['userID'];
// Get persons
$sql = 'SELECT * FROM persons WHERE id = $userID';
$q = $conn->query($sql) or die('failed!');
$sql = "SELECT * FROM persons WHERE id = $userID";
You must use double quotes to use variables inside the query string.
You can also do this:
$sql = "SELECT * FROM persons WHERE id = ".$userID;
What you should do is this (to protect yourself from sql injection):
$safeuid = $conn->prepare($userID);
$sql = "SELECT * FROM persons WHERE id = ".$safeuid;
You can always debug using this at the top of your php page:
ini_set('display_errors',1);
error_reporting(E_ALL);
Have you tried $q = $conn->query($sql) or die($conn->error()); ?
Yes you can, but you should only do it for debugging. Crackers can gain a lot of insight by purposefully feeding bad input and reading the error.
I'm assuming you're using MySQLi; the command is $conn->error(). So your line would be:
$q = $conn->query($sql) or die($conn->error());
Also, what you're doing wrong is you're using single quotes to define $sql. You need to use double quotes to write $userID into the string. So what you want is:
$sql = "SELECT * FROM persons WHERE id = $userID";
or
$sql = 'SELECT * FROM persons WHERE id = ' . $userID;
You need to use double quotes to evaluate variables within the string. That is,
$sql = 'SELECT * FROM persons WHERE id = $userID';
should be
$sql = "SELECT * FROM persons WHERE id = $userID";
Rather than removing the die you should make sure the query is always valid. In other words: validate the userID parameter. $_GET can contain anything the user wants to provide - it could be an array, it could be a string, it could be a string with a malicious payload that can drop your tables. So check it is an integer. If not, return a relevant message to the user.
Not a php expert but you might try:
// Get USER ID of person
$userID = $_GET['userID'];
// Get persons
$sql = 'SELECT * FROM persons WHERE id = $userID';
$q = $conn->query($sql) or die('failed!' . mysql_error());
The error should append to the end of your die message.

MySQL Select statement

I have 2 values that I'm suppling my script - I want to search for any one of those datas. How do I write my query like this:
SELECT * FROM table WHERE id = '".$id."' or "name='".$name."';
my problem is escaping the quotes in the query.
Any help will be appreciated.
There are a few ways to do it, a lot of them frowned on but generally I would stick to using MySQLi and using the
mysqli_real_escape_string($id)
function or in OOP
$mysqli = new mysqli('host', 'user', 'pass', 'database');
$id = $mysqli -> real_escape_string($id);
$name = $mysqli -> real_escape_string($name);
$results = $mysqli -> query("SELECT * FROM table WHERE id = '{$id}' or "name='{$name}'");
You may use curly brackets to avoid confusion with escaping characters as follows:
$query = "SELECT * FROM table WHERE id = '{$id}' or name = '{$name}' ";
You may also consider using wildcards such as %$letter% to search for word anywhere in the name field as:
$query = "SELECT * FROM table WHERE id = '{$id}' or name LIKE '%{$name}%' ";
SUGGESTTION:
You should always use id fields as integer for better performance.
Use this fancy function, mayhaps? The examples have what you're looking for.
You've got an extra quote; if you want to stick with your original code (not recommended), try something like this:
$query = "SELECT * FROM table WHERE id = '".$id."' or name='".$name."'";
But really you should be using parameterised queries so that you avoid possible SQL injection security issues!
Write it as:
$name = mysql_real_escape_string($name);
$id = mysql_real_escape_string($id);
$query = "SELECT * FROM table WHERE id = '$id' or name= '$name' ";
Because you started with double quotes the single quotes are part of the query and the $vars are expanded.

PHP Protect query from mysql Injection.

How can I add mysql_real_escape_string() to this:::
$result = mysql_send("INSERT customers SET user='$username', pword='$pass1',
firstname='$firstname', lastname='$lastname', email='$email',
active='No', activecode='$activecode', dateofbirth='$dateofbirth',
gender='$gender', title='$title', occupation='$occupation',
address='$address', city='$city', country='$country', zip='$zip',
mobile='$mobile', telephone='$telephone', fax='$fax',
website='$website'
");
$result = mysql_send(" INSERT customers
SET user='".mysql_real_escape_string($username)."',
pword='".mysql_real_escape_string($pass1)."',
firstname='".mysql_real_escape_string($firstname)."',
lastname='".mysql_real_escape_string($lastname)."',
email='".mysql_real_escape_string($email)."',
active='No',
activecode='".mysql_real_escape_string($activecode)."',
dateofbirth='".mysql_real_escape_string($dateofbirth)."',
gender='".mysql_real_escape_string($gender)."',
title='".mysql_real_escape_string($title)."',
occupation='".mysql_real_escape_string($occupation)."',
address='".mysql_real_escape_string($address)."',
city='".mysql_real_escape_string($city)."',
country='".mysql_real_escape_string($country)."',
zip='".mysql_real_escape_string($zip)."',
mobile='".mysql_real_escape_string($mobile)."',
telephone='".mysql_real_escape_string($telephone)."',
fax='".mysql_real_escape_string($fax)."',
website='".mysql_real_escape_string($website)."'
");
I make it this way (assuming HTML form's field names exactly match a database field name):
$fields = explode(" ","user pword firstname lastname email ative activecode dateofbirth gender title occupation address city country zip mobile telephone fax website");
$_POST['active'] = "Mo"; // I know it's kinda dirty but it works.
$sql = "INSERT INTO customers SET ".makeDdbSet($fields);
function makeDdbSet($fields) {
$q='';
foreach ($fields as $v) $q.="`$v` = '".mysql_real_escape_string($_POST[$v])."', ";
return trim($q,", ");
}
looks neat to me.
Maybe you can take some time and check out Doctrine ORM.
Saving to database would then look like:
$customer = new Customer();
$customer->fromArray($data); // $data = array("firstname"=>"John", ...)
$customer->save();
Everything will be escaped, your program will also be more readable ...
Escaping is quite old-school. Instead, use prepared statements to separate queries and data.
This saves you lots of headaches.
$sql = "INSERT customers SET user=:user, pword = :pword .....";
$sth = $dbh->prepare($sql);
$sth->execute(array('user => $username, 'pword' => $password));
Depending on where you get the data from, you might also directly have it in an array.
For example, in case you get a lot of data from a form, with the variable names pword, user and so on you can directly use that array
$sth->execute($_POST);
$result = mysql_send("INSERT customers SET user='$username', pword='$pass1', firstname='".mysql_real_escape_string($firstname)."', lastname='".mysql_real_escape_string($lastname)."', email='".mysql_real_escape_string($email)."', active='No', activecode='".mysql_real_escape_string($activecode)."', dateofbirth='".mysql_real_escape_string($dateofbirth)."', gender='".mysql_real_escape_string($gender)."', title='".mysql_real_escape_string($title)."', occupation='".mysql_real_escape_string($occupation)."', address='".mysql_real_escape_string($address)."', city='".mysql_real_escape_string($city)."', country='".mysql_real_escape_string($country)."', zip='".mysql_real_escape_string($zip)."', mobile='".mysql_real_escape_string($mobile)."', telephone='".mysql_real_escape_string($telephone)."', fax='".mysql_real_escape_string($fax)."', website='".mysql_real_escape_string($website)."'");

Categories