tags:

views:

107

answers:

2

Hi,

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=&amp;ands=&amp;phrase=&amp;ors=&amp;nots=RT%2C+%40&amp;tag=andyasks&amp;lang=all&amp;from=amcafee&amp;to=&amp;ref=&amp;near=&amp;within=15&amp;units=mi&amp;since=&amp;until=&amp;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?

A: 

PHP/MySQL Debugging Tips

  1. 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.

  2. 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.

  3. 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.

Alan Storm
Well, it was the copy/paste into MySQL that helped me. I need to have it escape quotes as it was prematurely truncating my data. Can you elaborate on the logging function? I'm not understanding just how I'd use it. Thanks for the tips.
Alex Mcp
Fixed the formatting on that. Basically you'd pass your sql string (or whatever) into the logger function and it'd spit the contents out into a file. You could then monitor the file instead of the web browser, and not get tripped up by encoding/escaping issues that might come up when viewing sql statments interpreted as HTML.
Alan Storm
+4  A: 

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=&amp;ands=&amp;phrase=&amp;ors=&amp;nots=RT%2C+%40&amp;tag=andyasks&amp;lang=all&amp;from=amcafee&amp;to=&amp;ref=&amp;near=&amp;within=15&amp;units=mi&amp;since=&amp;until=&amp;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);
    }
 }
Otterfan