I am using new wpdb for accessing database with wordpress.
$mydb = new wpdb($username,$password,$database,$hostname);
$sql = $mydb->prepare("SELECT * FROM " . $table);
$results = $mydb->get_results($sql);
This line produces error:
$sql = $mydb->prepare("SELECT * FROM " . $table);
wpdb::prepare was called incorrectly. wpdb::prepare() requires at least two arguments.
All below statements produce same error:
$sql = $mydb->prepare("SELECT * FROM $table");
$sql = $mydb->prepare("SELECT * FROM '%s'", $table);
How do I write it without arguments?
(I am using wordpress 3.5)
Take the single quotes off from '%s' in your last example and that should work assuming $table is a valid table name.
Edit: $wpdb->prepare() works similar to php's sprintf() on a more limited scale. If you just pass it a single parameter, it doesn't do anything. See Andrew Nacin's post on this after 3.5 was released: http://make.wordpress.org/core/2012/12/12/php-warning-missing-argument-2-for-wpdb-prepare/
The second parameter will replace the first instance of a replaceable character set, i.e. %s, %d or %f, and third parameter will replace the second instance, and so on.
Related
In my Wordpress plugin I have code snippets that look like this:
$total = $wpdb->get_var($wpdb->prepare(
"
SELECT SUM(Amount)
FROM $table_name
WHERE Account = $user_id AND Timestamp > {$balance['Timestamp']}
",NULL
));
It was working very well for years, but after I recently updated Wordpress to 5.0 I get many errors like this:
Fatal error: Uncaught ArgumentCountError: Too few arguments to function wpdb::prepare(), 1 passed in (...)/pluginfile.php on line 753 and exactly 2 expected in /wp-includes/wp-db.php:1222
Through my research I found that I need to use %s and %d in the wp prepare function but I didn't figure out how to apply it properly to the code above.
We use the 'prepare' method to make sure we're not sending an illegal operation or any illegal characters.
Try modifying your code to the following:
$total = $wpdb->get_var($wpdb->prepare(
"
SELECT SUM(Amount)
FROM $table_name
WHERE Account = %d AND Timestamp > %d
",
$user_id, $balance['Timestamp']
));
Both User ID and a timestamp are integers (whole numbers) so we would use %d.
Possible format values: %s as string; %d as integer (whole number); and %f as float.
For anybody that might run into a similar problem: with the help of the comment above by #entreprenerds I was able to fix the code as follows:
$total = $wpdb->get_var($wpdb->prepare(
"
SELECT SUM(Amount)
FROM $table_name
WHERE Account = %d AND Timestamp > %d
",$user_id, $balance['Timestamp']
));
Thanks!
I want to read query string from URL and save them into a sqlite database
I face with these Error message:
PHP Warning: SQLite3::exec(): near ",": syntax error
But I don't the problems:
$Tel = $_REQUEST["from"];
$Content = $_REQUEST["text"];
echo $Tel = strip_tags($Tel);
echo $Content = strip_tags($Content);
$sql =<<<EOF
INSERT INTO foodordering(Fullname, Tel, RecievingTime, Content)
VALUES ("Ehsan", $Tel, date('now'), $Content);
EOF;
$ret = $db->exec($sql);
As mentioned by #HassanAhmed, this is what happens when inputs are not properly handled; you're seeing the same issue as if someone was using SQL injection against you. The quick fix is to wrap the fields in quotation marks:
VALUES ("Ehsan", "$Tel", date('now'), "$Content");
What you should be doing is binding the parameters:
$sql =<<<EOF
INSERT INTO foodordering(Fullname, Tel, RecievingTime, Content)
VALUES ("Ehsan", :tel, date('now'), :content);
EOF;
$stmt = $db->prepare($sql);
$stmt->bindValue(':tel', $_REQUEST['from']);
$stmt->bindValue(':content', $_REQUEST['text']);
$ret = $stmt->execute();
If I query the database using this code, I get an array of 4 objects as expected.
global $wpdb;
$rows = $wpdb->get_results("SELECT * FROM ppm_playlists");
var_dump($rows); die();
But if I query using this, I get an empty array.
global $wpdb;
$rows = $wpdb->get_results("SELECT * FROM ppm_playlists ORDER BY sort-order ASC");
var_dump($rows); die();
Is there a "trick" to using "ORDER BY" in the database class that I am missing in the documentation?
Thanks in advance.
Replace sort-order ASC to sort_order ASC
When having problems like this it helps to put the problematic query in the phpMyAdmin to locate the problem.
The reason the query failed is because sort-order is interpreted as sort - order (subtracting the column named order from the column named sort). If you wish to keep the hyphen in your column name, you would have to wrap the column in backticks:
SELECT * FROM ppm_playlists ORDER BY `sort-order` ASC;
Note, however, that using hyphens in column names is not recommended.
I would like to filter a collection with grouped clauses. In SQL this would look something like:
SELECT * FROM `my_table` WHERE col1='x' AND (col2='y' OR col3='z')
How can I "translate" this to filtering a collection with ->addFieldToFilter(...)?
Thanks!
If your collection is an EAV type then this works well:
$collection = Mage::getResourceModel('yourmodule/model_collection')
->addAttributeToFilter('col1', 'x')
->addAttributeToFilter(array(
array('attribute'=>'col2', 'eq'=>'y'),
array('attribute'=>'col3', 'eq'=>'z'),
));
However if you're stuck with a flat table I don't think addFieldToFilter works in quite the same way. One alternative is to use the select object directly.
$collection = Mage::getResourceModel('yourmodule/model_collection')
->addFieldToFilter('col1', 'x');
$collection->getSelect()
->where('col2 = ?', 'y')
->orWhere('col3 = ?', 'z');
But the failing of this is the order of operators. You willl get a query like SELECT * FROM my_table WHERE (col1='x') AND (col2='y') OR (col3='z'). The OR doesn't take precedence here, to get around it means being more specific...
$collection = Mage::getResourceModel('yourmodule/model_collection')
->addFieldToFilter('col1', 'x');
$select = $collection->getSelect();
$adapter = $select->getAdapter();
$select->where(sprintf('(col2 = %s) OR (col3 = %s)', $adapter->quote('x'), $adapter->quote('y')));
It is unsafe to pass values unquoted, here the adapter is being used to safely quote them.
Finally, if col2 and col3 are actually the same, if you're OR-ing for values within a single column, then you can use this shorthand:
$collection = Mage::getResourceModel('yourmodule/model_collection')
->addFieldToFilter('col1', 'x')
->addFieldToFilter('col2', 'in'=>array('y', 'z'));
I am doing the following:
$type = 'attachment';
$images = $wpdb->get_results($wpdb->prepare('
SELECT p.*
FROM wp_%d_posts p
WHERE p.post_parent =%d
AND p.post_type = "%s"
', $blog_id, $page->ID, $type),OBJECT);
var_dump($images);
If I remove the line 'AND p.post_type = "%s"' then I get results returned, otherwise I get an empty array returned. If I run the query direct against the DB in a mysql client, I get results.
There is no error, just an empty result set. I am doing similar queries throughout my file and they are working so I'm not looking for "don't do it like that" style replies. I just need to understand why this isn't working and fix it.
PHP 5.3, MYSQL 5.1. WordPress MU 2.9.2
Do not Quote "%s". From the WordPress site, "Notice that you do not have to worry about quoting strings. Instead of passing the variables directly into the SQL query, use a %s placeholder for strings and a %d placedolder for integers."
Example:
$wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET post_title = %s WHERE ID = %d", $var, $id ) );