Why doesn't this custom table $wpdb query work? - mysql

I have a custom table called wp_purchases that is added to by a Paypal IPN, it has the columns post_id, purchase_id, username, email and changes:
$user = $_POST['username'];
$post_id = $post->ID;
global $wpdb;
$wpdb->purchases = $table_prefix . 'purchases';
$result = $wpdb->query("SELECT * FROM $wpdb->purchases WHERE username = $user AND post_id = $post_id");
if ($result) {...
I'm just trying to check if there is a purchase under a certain username in a single .php theme page and then perform an operation unrelated to the $result.
It won't work though, any way I try it comes up with null. Is it something to do with using $wpdb->purchases or not including a certain file or something else? I've also tried it with get_results and get_row with no luck.

Try this :
$result = $wpdb->query("SELECT * FROM `".$wpdb->purchases."` WHERE username = '$user' AND post_id = '$post_id';");

I gave up and just used
$result = $wpdb->query("SELECT * FROM wp_purchases WHERE username = $user AND post_id = $post_id");
because it's for a single site and doesn't really need the table prefix, it'll always be wp_

I know it's too late for this answer, but I'll still post it for the sake of others who are also having similar issue.
You mentioned that the query still returns nothing even after removing the WHERE part, have you tried to echo $wpdb->purchases variable? It might just returning you a string "purchases" instead of "wp_purchases" (assuming that your table prefix is "wp_"). Try using $wpdb->prefix instead of $table_prefix, or $wpdb->base_prefix if you got a multisite.
$wpdb->purchases = $wpdb->prefix . 'purchases';

What type of username? I assume it stores string data. So variable $user must be quoted:
"SELECT * FROM $wpdb->purchases WHERE username = \"$user\" AND post_id = $post_id"

Related

Login with url paramaters

I'm creating a login system of sorts that uses parameters from the URL.
The parameters are set no problem. I dont know what the issue is.
Here's my code:
<?php
require_once("db_const.php");
$mysqli = new mysqli("dont", "try", "to login to", "my database");
# check connection
if ($mysqli->connect_errno) {
echo "<p>MySQL error no {$mysqli->connect_errno} : {$mysqli->connect_error}</p>";
exit();
}
$username = filter_input(INPUT_GET,"username",FILTER_SANITIZE_STRING);
$password = filter_input(INPUT_GET,"password",FILTER_SANITIZE_STRING);
$sql = "SELECT * from users WHERE username LIKE '{$username}' AND password LIKE '{$password}' LIMIT 1";
$result = $mysqli->query($sql);
if (!$result->num_rows == 1) {
echo "failed";
} else {
echo "success";
}
?>
There are a few problems with your code.
The problem is the use of the LIKE function. Your usage is
SELECT * from users WHERE username LIKE '{$username}' AND password LIKE '{$password}' LIMIT 1
Like requires additional specification to find match positions and such, for example :
SELECT ... WHERE username LIKE '%{$username}%'
In the form you used, the WHERE clause if equivalent to
SELECT ... WHERE username = '{$username}'
In addition, LIKE is not recommended even (especially) with the wildcards, as 'tom' will match users 'tom' and 'tommy', and the count will certainly not be == 1.
I'll also urge you to test the query for errors
if (!$result) {
echo 'An error occurred : $mysqli->error;
}
Others have already mentioned the risk in passwing username and passwords on the URL, Please take note of their comments.
In addition, storing the password in plain form the database is not recommended for security reasons. There are plenty of resources explaining how to encrypt passwords and authenticate using the encrypted values.
Try:
$sql = "SELECT * from users WHERE username='$username' AND password='$password'";
CAUTION
Even if the above code solves your problem, It's still very dangerous as it's vulnerable for SQL injection on both username and password parameters and it can be exploited in a manner that a malicious user can bypass the login check by breaking out of the quotes and adding a condition that evaluates to true.
You can use a mysqli::prepare to get over that.
$stmt = mysqli->prepare("SELECT * from users WHERE username=? AND password=?");
$stmt->bind_param("ss", $username,$password);
$stmt->execute();

Will my code prevent SQL injection

i have searched and added some prevention code but i need expert advice am i correct ?
I have made seperate file for SQL connect but i have confusion whether i should use include, require, include_onces or any other ?
mysql_connect("localhost", "userr", "pass") or die(mysql_error()) ;
mysql_select_db("databse") or die(mysql_error()) ;
Here i have added two things UTF8 and mysql_real_escape_string.
$bad='anyone123';
$var = mysql_real_escape_string($bad);
$q = mysql_query('SET user_id UTF8');
$q = mysql_query("SELECT * FROM fbusers WHERE user_id = '$var'");
$r = mysql_fetch_array($q);
Please give me advice if how can i prevent injec. to 100%
i don't want my website to be hacked :(
Thank you
You need to use prepared statements for any queries that require user input. This sends the query and the parameters seperately and acts as a layer of security to catch any malicious input.
In PDO:
$stmt = $pdo->prepare("SELECT * FROM fbusers WHERE user_id = :var");
$stmt->execute(array(':var'=>$var));
In mysqli:
$stmt = $dbConnection->prepare('SELECT * FROM fbusers WHERE user_id = ?');
$stmt->bind_param('s', $var);
$stmt->execute();
Maybe this post would help.

How to display the values returned by count in SQL

i keep having this error "mysql_fetch_array() expects parameter 1 to be resource, null given in" when i try to display the returned value of count in sql. heres my code.
$query="SELECT med_rec_ID, COUNT(med_rec_ID)
FROM med_issue
WHERE MONTH(issue_date) = MONTH('2013-02-05')
GROUP BY med_rec_ID";
$result= mysql_query($query);
while($count = mysql_fetch_array($display3)){
echo $count[0];
}
i have tried to run the query in sql alone it displays 2 columns (the med_rec_ID, and the COUNT). guys how do i display the count and fix the error too?
First of all, don't use mysql_* functions since they're deprecated. Use mysqli or PDO.
Secondly, look at what you're passing into the fetch_array function.
You probably want to do something like:
$link = mysqli_connect("localhost", "admin", "pass", "db_name");
$result = mysqli_query($link, $sql);
while($row = $result->fetch_array(MYSQLI_ASSOC)){
$medIds[] = $row['med_rec_ID'];
...
}
Then fix the count by giving it an alias.
Please note that you should actually store how you access the DB in a more secure manner, but I use this only to illustrate the example. Here's a pretty good post: How to create global configuration file?
Is your query even executing? that error will happen if mysql_query doesnt return the resource, in case query fails
$query="SELECT med_rec_ID, COUNT(med_rec_ID) as C FROM med_issue where MONTH(issue_date) = MONTH('2013-02-05') GROUP BY med_rec_ID";
$result= mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_assoc($result))
{
echo $row["C"];
}
Note: Please do not use mysql_* functions anymore
Give it an alias:
SELECT
med_rec_ID,
COUNT(med_rec_ID) TheCount
FROM med_issue
where MONTH(issue_date) = MONTH('2013-02-05') GROUP BY med_rec_ID
then you can select that column TheCount inside the while loop with $row['TheCount'], also use lope through the $result:
$result = mysql_query($query);
while($row = mysql_fetch_array($result)){
echo $row['TheCount'];
}

Selecting MYSQL rows with same field names and adding a prefix

I'm trying to make a mysql query to select several tables and LEFT join them, however they all have same columns names 'user' etc. I want to rename all the fields in this manner . so I tried the following query
SELECT mod_backup_accounts . * AS account . * , mod_backup_subscriptions . *
FROM `mod_backup_accounts`
LEFT JOIN `mod_backup_subscriptions` ON `mod_backup_accounts`.subscription_id = `mod_backup_subscriptions`.package_id
However the mod_backup_accounts . * AS account . * makes it fail, is there a way to do this? so it would be names as account.
You cannot supply a shorthand to alias columns you must do it explicitly for each column name. In general anyway, it is typically recommended to name all columns explicitly in the SELECT list rather than using SELECT *, since it allows you to deterministically specify the column order, and protects you against accidentally pulling in a large BLOB later on if one ever gets added to the table ( or any other schema changes ).
SELECT
mod_backup_accounts.user AS account_user,
mod_backup_subscriptions.user AS subscription_user,
...
...
FROM
mod_backup_accounts
LEFT JOIN `mod_backup_subscriptions` ON `mod_backup_accounts`.subscription_id = `mod_backup_subscriptions`.package_id
I totally understand your problem about duplicated field names.
I needed that too until I coded my own function to solve it. If you are using PHP you can use it, or code yours in the language you are using for if you have this following facilities.
The trick here is that mysql_field_table() returns the table name and mysql_field_name() the field for each row in the result if it's got with mysql_num_fields() so you can mix them in a new array.
You can also modify the function to only add the "column." prefix when the field name is duplicated.
Regards,
function mysql_rows_with_columns($query) {
$result = mysql_query($query);
if (!$result) return false; // mysql_error() could be used outside
$fields = mysql_num_fields($result);
$rows = array();
while ($row = mysql_fetch_row($result)) {
$newRow = array();
for ($i=0; $i<$fields; $i++) {
$table = mysql_field_table($result, $i);
$name = mysql_field_name($result, $i);
$newRow[$table . "." . $name] = $row[$i];
}
$rows[] = $newRow;
}
mysql_free_result($result);
return $rows;
}

Codeigniter DB or URI problem with unicode

I'm having a weird problem.
I have this code
$topic contains "海賊_(ONE_PIECE)" from URI /trends/about/海賊_(ONE_PIECE)
I checked to echo $topic and it prints out 海賊_(ONE_PIECE)
$sql="SELECT wti.redirect_title FROM wikipedia_timelines AS wti WHERE wti.redirect_title = ? LIMIT 1";
$query = $this->db->query($sql,array($topic));
if ($row = $query->result_array())
{
The problem is that this code returns $row to be an empty array
Array
(
[0] => Array
(
[redirect_title] =>
)
)
However, if I use this code (replacing ? with the actual value of $topic, it works perfectly
$sql="SELECT wti.redirect_title FROM wikipedia_timelines AS wti WHERE wti.redirect_title = '海賊_(ONE_PIECE)' LIMIT 1";
$query = $this->db->query($sql,array($topic));
if ($row = $query->result_array())
{
Replacing ? with {$topic} will not make it working too.
This problem only occurs when $topic contains ( ) if it doesn't have () it works fine
I wonder what is the problem.
I suppose there is a problem with URI encoding, but I'm not sure how to fix it.
Please help me.
Thank you
I'm pretty sure your problem is that query binding escapes your input values (im guessing it doesn't like brackets).
try building your sql string with concatenation, like:
$sql = "SELECT wti.redirect_title FROM wikipedia_timelines AS wti WHERE wti.redirect_title = '".$topic."' LIMIT 1";
$query = $this->db->query($sql);
and see if that helps. Or try the active record class, I use it for japanese characters all the time and it seems to work ok.
// EDIT:
To allow brackets in the URI, try and change application/config.config.php and set
$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-()';
also try urldecode($topic); to get the kanji out.