This REGEXP echos one thing, but enters into MySQL another. Why? - php

I have a query that when I test it with "echo", works well:
$url = "http://search.twitter.com/search.json?q=&ands=&phrase=&ors=&nots=RT%2C+%40&tag=andyasks&lang=all&from=amcafee&to=&ref=&near=&within=15&units=mi&since=&until=&rpp=50";
$contents = file_get_contents($url);
$decode = json_decode($contents, true);
foreach($decode['results'] as $current) {
if(preg_match("/\?/", "$current[text]")){
echo $current[text]."<br />";
}
}
But when I change it to this to create a DB, it loses one record:
$url = "http://search.twitter.com/search.json?q=&ands=&phrase=&ors=&nots=RT%2C+%40&tag=andyasks&lang=all&from=amcafee&to=&ref=&near=&within=15&units=mi&since=&until=&rpp=50";
$contents = file_get_contents($url);
$decode = json_decode($contents, true);
foreach($decode['results'] as $current) {
$query = "INSERT IGNORE INTO andyasks (questions, date, user) VALUES ('$current[text]','$current[created_at]','Andy')";
if(preg_match("/\?/", "$current[text]")){
mysql_query($query);
}
}
Specifically, the Tweet it's skipping over is "amcafee: #andyasks What should Enterprise 2.0 conference attendees be sure to do while they're in Boston later this month? #e2conf". This echos from the first one, but is left out on the DB INSERT. Any thoughts?

There's a single quote in the string that it doesn't insert (my _emphasis_ added):
"amcafee: #andyasks What should Enterprise 2.0 conference attendees be sure to do while they**_'_**re in Boston later this month? #e2conf"
The bare single-quote is interpreted by MySQL as the end of the first value, and it turns the rest of the query into gibberish. You need to escape single quotes (i.e. turn "they're" into "they\'re" so that MySQL knows that the single quote is part of your string. Incidentally, single-quote tricks are the main source of SQL injection attacks, so you should always be wary of single-quotes.
If you're using the mysql extension, you should always use the mysql_real_escape_string function on any untrusted data:
$url = "http://search.twitter.com/search.jsonq=&ands=&phrase=&ors=&nots=RT%2C+%40&tag=andyasks&lang=all&from=amcafee&to=&ref=&near=&within=15&units=mi&since=&until=&rpp=50";
$contents = file_get_contents($url);
$decode = json_decode($contents, true);
foreach($decode['results'] as $current)
{
$query = "INSERT IGNORE INTO andyasks (questions, date, user) VALUES ('$current[text]','$current[created_at]','Andy')";
if(preg_match("/\?/", "$current[text]"))
{
mysql_real_escape_string($query);
mysql_query($query);
}
}

PHP/MySQL Debugging Tips
When you're echoing out debug statements, make sure you view the source of your HTML page to see what's actually being sent to mysql.
While viewing the source of your echo'd page, copy and paste the SQL query directly into the mysql console (or phpMyAdmin if you're using it) and see what happens.
Consider using a logging function instead of echoing out mysql statements. Here's a brain dead logger you can use
class BrainDeadLogger {
static public function log($output, $file='/tmp/test.txt') {
file_put_contents($file,"$output\n",FILE_APPEND);
}
}
BrainDeadLogger::log($sql);
And then monitor the log with something like
tail -f /tmp/test.txt
on the Unix command line. You can downloadTail for Windows, which should work similarly.

Related

Escaping apostrophe in a dynamically created array in PHP

I'm working on a project to blend a number of different data sets within a PostgreSQL database. I still consider myself a beginner with PHP development and scripting. I am having some real trouble with escaping the apostrophes within the arrays. I tried a few different solutions from these forums: An escaped apostrophe in associative array value, Replace apostrophe in a dynamically created insert statement, http://www.codingforums.com/php/296075-array_walk_recursive-w-function-takes-2-parameters-mysqli_real_escape_string.html, and finally here Escaping quotation marks in PHP. I'm currently trying to recreate my script with a PDO version so I do not have to sanitize my text. At least that is what I understand is the better approach from all of the research I have done. What I'm currently looking for is a method to escape the characters while I find a more eloquent solution. Here is the main piece of code I'm using for the import process:
<?php
include('connect_local.php'); //Includes DB Connection Script
ini_set('max_execution_time', 3000); //3000 seconds = 50 minutes
$emp_get = "SELECT * FROM table1 WHERE person_type LIKE 'Employee'";
$emp_data = pg_query($conn, $emp_get);
while ($emp_row=pg_fetch_array($emp_data)) {
$oraint_get = "SELECT * FROM table2 WHERE source_enrollment_status_name LIKE 'Attended' AND employee_number LIKE '$emp_row[0]' ";
$oraint_data = pg_query($conn, $oraint_get);
$oraint_lms = "Oracle Learning Management Platform";
$oranull = "";
//foreach ($oraint_row as $oraint)
while ($oraint_row = pg_fetch_array($oraint_data)){
$data_deposit = "INSERT INTO EDU_DATA (person_number, person_name, preferred_name, person_type, start_date, original_date_of_hire
,hire_date, email_address, region, location, gender, job_name, cbs_level, supervisor_employee_number
,supervisor_name, supervisor_person_type, business_unit, organization_2, organization_3, effective_date
,completion_date, training_item_code, days_on_to_do_list, days_overdue, initial_due_in, initial_due_in_unit
,retraining_due_in, retraining_due_in_unit, retraining_period, retraining_period_unit
,curriculum_code, curriculum_title, learning_course_name, learning_activity, class_duration, college, delivery_method_name
,class_location_name, class_location_country_name, learning_category, source_enrollment_status_name, lms_platform
,supervisor_1 ,supervisor_2, supervisor_3, supervisor_4, supervisor_5, supervisor_6, supervisor_7, supervisor_8)
VALUES ('$emp_row[0]','$emp_row[1]','$emp_row[2]','$emp_row[4]','$emp_row[5]','$emp_row[6]','$emp_row[8]'
,'$emp_row[9]','$emp_row[16]','$emp_row[17]','$emp_row[19]','$emp_row[21]','$emp_row[22]','$emp_row[28]'
,'$emp_row[29]','$emp_row[30]','$emp_row[33]','$emp_row[44]','$emp_row[45]','$oraint_row[2]','$oraint_row[3]'
,'$oranull','$oranull','$oranull','$oranull','$oranull','$oranull','$oranull','$oranull','$oranull','$oranull'
,'$oranull','$oraint_row[4]','$oraint_row[5]','$oraint_row[6]','$oraint_row[7]','$oraint_row[8]','$oraint_row[9]'
,'$oraint_row[10]','$oraint_row[11]','$oraint_row[12]','$oraint_lms','$emp_row[46]','$emp_row[47]','$emp_row[48]'
,'$emp_row[49]','$emp_row[50]','$emp_row[51]','$emp_row[52]','$emp_row[53]')";
pg_query($conn, $data_deposit);
In my attempts to sanitize the text I have tried turning the array output into a string and then using addslashes without any success:
$clnname = $emp_row[1];
addslashes($clnname);
I also tried creating a function to handle this for me recursively using the example I found here: Escape single quotes in every string in php. The code snippet is the following:
function escapeApos(array $emp_row)
{
$return_array = [];
array_walk_recursive($emp_row, function($x) use (&$return_array)
{
$return_array[] = str_replace("'","\\'",$x);
}
return $return_array;
}
I have also tried a few other ways without any success. Any aid or assistance will be greatly appreciated. Also with the above function I was not sure if I needed to declare the actual column in the array that I wanted to have sanitized. Again any assistance is welcome! Thank you in advance!
Alright, HUGE thanks to everyone for helping me out! I started recreating the script using PDO instead of the first approach I took. Here is a sample of the script, I have some work ahead of me. However, now that I'm using PDO, the issues with sanitizing the text is a non-issue. I'm going to use this method from now on!
<?php
include('connect_local_pdo.php'); //Includes DB Connection Script
ini_set('max_execution_time', 3000); //3000 seconds = 50 minutes
try {
$stmt = $conn->query('SELECT * FROM table1');
$rows = $stmt->setFetchMode(PDO::FETCH_ASSOC);
while ($rows = $stmt->fetch()) {
$emp_id = $rows['person_number'];
$stmt2 = $conn->query("SELECT * FROM table2 WHERE employee_number LIKE '$emp_id'");
$oracleint = $stmt2->setFetchMode(PDO::FETCH_ASSOC);
while ($oracleint = $stmt2->fetch()) {
$GO = $conn->prepare("INSERT INTO table3 (person_number, person_name, learning_course_name) VALUES (:emp_number, :emp_name, :learning_course_name)");
$GO->bindParam(':emp_number', $rows['person_number']);
$GO->bindParam(':emp_name', $rows['person_name']);
$GO->bindParam(':learning_course_name', $oracleint['learning_course_name']);
$GO->execute();
}
}
} catch (PDOException $b) {
echo 'Data Extraction Failed: ' . $b->getMessage();
}
Again, thanks for assisting the newbie! I totally love StackExchange!! You guys ROCK!

Handle POST request in JSON format

I'm trying to handle a POST request from a web service. It's sending an HTTP POST request like this:
{
"latitude":"12.232",
"longitude":"123.323"
}
It's posting to a PHP file on my server. I know that it is hitting the file for sure. However, I'm not getting the data.
In my PHP, I have this (leaving out a bunch of stuff:
$json = file_get_contents('php://input');
$obj = json_decode($json);
$mine ="sixteen"; //using this for a test
$sql = "INSERT INTO rr_emergency (random) VALUES('$obj');";
$result = $dbh->query($sql)->fetchAll(PDO::FETCH_ASSOC);
This makes no change to my database.
If I do this instead:
$sql = "INSERT INTO rr_emergency (random) VALUES('$mine');";
Then "sixteen" is added in the right spot in a new row in my table each time the webservice calls my PHP. This is how I know I'm receiving data.
NOTE: I was trying to simply add $obj into my table just to see the data format that's returned before I tried to properly parse it and put everything where it belongs.
What am I doing wrong here? I think the problem is here ($json = file_get_contents('php://input');), but not sure what else to try.
Thanks.
So there's a few problems
$obj = json_decode($json);
This will return an object. You want an array
$obj = json_decode($json, true);
Then your PDO is incorrect
$sql = "INSERT INTO rr_emergency (random) VALUES(:val);";
$prep = $dbh->prepare($sql);
foreach($obj as $row) $prep->execute([':val' => $row]);
This will insert your data correctly (using a prepared statement) and loop over the JSON return data
You're trying to insert an object, when you really need a string. use:
$obj = json_decode($json, true)
$obj_str = implode(", ", $obj);
$sql = "INSERT INTO rr_emergency (random) VALUES('$obj_str');";
After I posted the above, you added:
I was trying to simply add $obj into my table just to see the data
format
Objects do not inherently convert to strings, so putting $obj within your query doesn't work. The way I store objects in my DB when I've needed to, is to store the JSON notation directly.
$json = file_get_contents("php://input");
$sql = "INSERT INTO rr_emergency (random) VALUES('$json')";
You lose the ability to perform filtering and selecting operations within the object, but it's an effective way to pack away data that you won't need the DB to parse through.
If you need well formatted, easy to read structure:
$obj = json_decode($json);
$obj_str = print_r($obj,true); //store formatted string
$sql = "INSERT INTO rr_emergency (random) VALUES('$obj_str');";
If as you said, all you need to do is "just see the data format", I suggest echoing to the screen or writing to a log file; do one of the following. To print to screen:
print_r($obj);
To write to file:
$filepath = "/path/to/file.txt"
file_put_contents($filepath,print_r($obj,true));
Important note
Entering text directly into your DB queries without escaping it makes you vulnerable to SQL injection attacks. Use prepared statements instead.

php insert data from fetch array to other table on version 5.4

I have moved to IIS 8 in PHP 5.4. I am trying to collect data from a table and insert them to a different one, i know my code is correct, but seems to be not working, probably because of the php version, can anyone help me?
here's my code
$query = odbc_exec($conn, "SELECT * FROM member");
while($rows = odbc_fetch_array($query)) {
$querystring = "INSERT INTO oldusers (username, password, regdate) VALUES ('$rows['userid']', '$rows['passwd']', '$rows['registdate']')";
$query2 = odbc_exec($conn, $querystring);
odbc_free_result($query2);
//echo $rows['userid']." ".$rows['passwd']." ".$rows['registdate']."<br>";
}
thanks in advance.
instead trying to insert one by one record, better to insert like below:
INSERT INTO oldusers (username, password, regdate) SELECT userid,passwd,registdate FROM member
for more information :http://dev.mysql.com/doc/refman/5.5/en/insert-select.html
You're placing $rows['passwd'] inside of a double-quoted string. Instead you should do:
$str = "some sql $rows[passwd] rest of sql"; // notice the absence of single quotes
or:
$str = "some sql {$rows['passwd']} rest of sql";
or (I think this way is most readable):
$str = 'some sql' . $rows[passwd] . ' rest of sql';
If your column contains text you'll need to add surrounding single quotes where necessary.
Having said all that, you should instead use parameterized queries (if your database supports it) as it's safer (from SQL injection). If that's unavailable you will at the very least need to escape the data before concatenating it to the string.

Implode array & search for matches mysql php

I'm trying to take an array and implode it and than run it through a mysql query to search my database for matches. If there are matches, I wanna return the matching values. It keeps returning false and I'm not sure why. I did a vardump and can see the array is there, but doesn't seem to be getting passed to the mysql_query. If I manually put the array into the query it works no problem. Any ideas?
My Array (This comes from my Android App):
$refids = (jdu23764js84, 2746272jsjs7f, 39823874hbsjsk)
PHP script code:
public function searchList($refids) {
$refarray = array($refids);
$comma_separated = implode(',', $refarray);
$result = mysql_query("SELECT `ref_id` FROM `main` WHERE `ref_id` IN
({$comma_separated})");
if ($result == true){
$result = mysql_fetch_array($result);
return $result;
} else {
return false;
}
You've forgotten to quote the individual values inside your $refids, so you're building
... WHERE `ref_id` IN (jdu23764js84, 2746272jsjs7f, ...)
and MySQL is interpreting those as field names. In other words, you're suffering from an SQL injection attack vulnerability, and your utter lack of ANY error handling on the database code is preventing from seeing the errors mysql is trying to tell you about:
$csv = implode("','", $refarray);
^-^-- note the addition of the quotes:
$sql = "SELECT .... `ref_id` IN ('{$csv}')";
^------^--- again, note the quotes
This fixes the problem in the short term. In the long term, you need to read through http://bobby-tables.com and learn what it has to tell you.

Problems with mysql_real_escape_string

I have field called filter1 on a form, I would like to be able to save quoted text into mysql. So I would like to be able to save the value "foo bar"...instead its saving just /
Here is what I have:
$keyword1 = mysql_real_escape_string($_POST['filter1']);
Any help is appreciated.
Here is how I construct the query
$keyword1 = mysql_real_escape_string($_POST['filter1']);
$keyword2 = $_POST['filter2'];//."|".$_POST['filterby'];
$keyword3 = $_POST['filter3'];//."|".$_POST['filterby2'];
$urlfilter1 = $_POST['url1'];
$urlfilter2 = $_POST['url2'];//."|".$_POST['url_filter'];
$urlfilter3 = $_POST['url3'];//."|".$_POST['url_filter2'];
//echo "combo_id:".$num." <BR></br>";
//echo "status:".$status." <BR></br>";
//echo "saveQuery:".$saveQuery." <BR></br>";
//$myFilter = "save";
$insert_query = sprintf("UPDATE COMBINATION
SET STATUS_ID=%s, QUERY=\"%s\",
KEYWORD1=\"%s\", KEYWORD2=\"%s\", KEYWORD3=\"%s\",
URLFILTER1=\"%s\", URLFILTER2=\"%s\", URLFILTER3=\"%s\"
WHERE COMBINATION_ID=%s",$status,$saveQuery,
$keyword1,$keyword2,$keyword3,
$urlfilter1,$urlfilter2,$urlfilter3,
$num);
//echo "insert_query:".$insert_query." <BR></br>";
$result = mysql_query($insert_query) or die(mysql_error());
if($result)
{
echo "Saved successfully<br>";
}
}
?>
Unless you have a very old and restricted environment, use PDO. It will save you buckets of sweat and tears. With PDO it is very easy to escape input and avoid SQL injection attacks, which is illustrated in the answer that this link leads to.
Well first you need to connect to the database with mysql_connect() http://php.net/manual/en/function.mysql-connect.php
Then you need to call your INSERT query with mysql_query() http://php.net/manual/en/function.mysql-query.php
By the way, you are doing the right thing by escaping the string before putting it into a query, well done :)
For some reason you are escaping only one variable, while adding to the query several of them.
Why don't you escape them all?
However, your problem may be somewhere else.
What is $saveQuery I am curious?

Categories