I am PDO newbie, and i can't figure why i can select only first row in Table on database.
This is my DataBase TABLE :
Column Type Null Default Comments
id int(11) No
cred varchar(20) No
tok char(40) No
ptok char(40) No
t char(128) No
expires varchar(26) No
Indexes
Keyname Type Unique Packed Column Cardinality Collation Null Comment
PRIMARY BTREE Yes No id 1 A No
ptok BTREE Yes No ptok 1 A No
And this is my SELECT (find) function :
public function findTriplet($credential,$token, $persistentToken) {
$sql = "SELECT IF(SHA1(?) = {$this->tokenColumn}, 1, -1) AS token_match " .
"FROM {$this->tableName} WHERE {$this->credentialColumn} = ? " .
"AND {$this->persistentTokenColumn} = SHA1(?) LIMIT 1 ";
$query = $this->connection->prepare($sql);
$query->execute(array($token, $credential, $persistentToken));
$result = $query->fetchColumn();
if(!$result) {
return self::TRIPLET_NOT_FOUND;
}
elseif ($result == 1) {
return self::TRIPLET_FOUND;
}
else {
return self::TRIPLET_INVALID;
}
}
Anyway i tryed to search for answer , but i dont know PDO so good so its not matter..
I tryed play with that , no succses..
Anyone know what is my problem in the findTriplet function and what i am doing wrong ?
It will only select first database row so if i have more then 1 row's it will return false.
Thanks allot.
Remove "LIMIT 1" from your variable and see if results change:
$sql = "SELECT IF(SHA1(?) = {$this->tokenColumn}, 1, -1) AS token_match " .
"FROM {$this->tableName} WHERE {$this->credentialColumn} = ? " .
"AND {$this->persistentTokenColumn} = SHA1(?) LIMIT 1 ";
Becomes:
$sql = "SELECT IF(SHA1(?) = {$this->tokenColumn}, 1, -1) AS token_match " .
"FROM {$this->tableName} WHERE {$this->credentialColumn} = ? " .
"AND {$this->persistentTokenColumn} = SHA1(?)";
It appears you are retrieving a match, so you are seeing a SINGLE result. I'm not sure of the application, but you might want to keep a Limit in the SQL statement. Removing the LIMIT will at least be a good testing point.
Related
Hello I have the following query which, theoretically, should gather all entrees in a table with a column value equal to any one of the values inside of the array. Here is my code:
$currentname = mysql_query("SELECT * FROM `entree` WHERE `user` IN(".implode(',',$AllFollows).") AND (`type` == '0' OR `type` == '1') ORDER BY id DESC LIMIT 0, $endtime;");
There is only one problem with it, it does not work and I have absolutely now idea why. Can someone please tell me what I have done wrong that causes it to disfunction is the expected manner?
Your IN content is not formed correctly ( you pass a value inside double quete not a list of value ) ..try
$my_in_value = "";
foreach ($AllFollows as $key => $value) {
if ($my_in_value == "" ) {
$my_in_value = $value;
} else{
$my_in_value = $my_in_value. ", ". $value . " ";
}
}
$currentname = mysql_query("SELECT *
FROM `entree`
WHERE `user` IN (" . $my_in_value ")
AND (`type` == '0' OR `type` == '1')
ORDER BY id DESC LIMIT 0, $endtime;");
I am trying to make my coding more efficient and I am stuck at how to tell the query to display all the categories if nothing is selected.
I have 15 categories that the user can chose from, if none is selected, display all items. Rather than doing AND .. AND .. AND 15 times if nothing is selected, is there a smarter way for this?
This will work for one category selection:
$cate = mysql_query("SELECT * FROM `posts` ORDER BY `id` ASC");
while($row = mysql_fetch_assoc($cate)){
if($user_data['category'] === $row['id']) {
echo '<li>'.$row['name'].'</li>';
}
}
$category_list = "AND `category_id` = '".$user_data['category']."'";
You should generate your query dynamically
// General query
$query = "SELECT * FROM `posts`";
// If category selected
if ($user_data['category'] != 0) {
$query .= " WHERE `category_id` = '".$user_data['category']."'";
}
// Order
$query .= " ORDER BY `id` ASC";
// Run query
$cate = mysql_query($query);
Or it can be simplified using Ternary Operator:
// Generate query
$query = "SELECT * FROM `posts` ".($user_data['category'] != 0 ? "WHERE `category_id` = '".$user_data['category']."'" : "" )." ORDER BY `id` ASC";
// Run query
$cate = mysql_query($query);
I have a page where you can filter users by their profile information.
I had 4 different filters that were "City", "Age Above", "Age Below", and "Gender".
I made it work this way, putting every possible combination as an if statement so that all the filters could work separately or in any combination:
if (isset($ageabove)
&& empty($agebelow)
&& empty($gender)
&& empty($city)
)
{
$sql = mysqli_query($con, "select * from Users1
WHERE age >= 1
");
}
This worked, but it was a lot of combinations and I did fear that this may be an inefficient way to do it.
Now I decided that I need to add 1 more filter, making it a total of 5 filters. This would increase the amount 'if' statements exponentially and I am wondering if there is a better way to accomplish this?
If I haven't been clear enough, please let me know.
Any help much appreciated!
$query = "SELECT stuff FROM table WHERE foo=1 ";
if ($filter1) {
$query .= "AND filter1 = $val";
}
if ($filter2) {
$query .= "AND filter2 = $val";
}
// run query
Would something like that work? (if (isset($filter1) && !empty($filter1))..)
Don't store age in a database. Unless the user specifically goes in and edits it they will be whatever age they signed up as forever. Store their birthdate and calculate age on the fly with:
SELECT DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(dob, '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(dob, '00-%m-%d')) AS age
I prefer to do this for dynamic conditions in SQL queries:
$query = 'SELECT * FROM table';
$conditions = array();
$parameters = array();
if( isset($_GET['cond1']) ) {
$parameters[] = $_GET['cond1'];
$conditions = 'column1 = ?';
}
if( isset($_GET['cond2']) ) {
$parameters[] = $_GET['cond2'];
$conditions = 'column2 = ?';
}
// etcetera...
if( ! empty(conditions) ) {
$query .= ' WHERE ' . implode(' AND ', $conditions);
$sth = $db->prepare($query);
$rs = $sth->(execute($parameters));
} else {
$sth = $db->prepare($query);
$rs = $sth->(execute());
}
if( ! $rs ) { /* error message */ }
// yadda yadda yadda
Which will build you a query like:
SELECT * FROM TABLE WHERE column1 = ? AND column2 = ? AND ... columnN = ?
as well as placing all of your arguments into the array in the proper order.
I might be a little squiffy on the parameterization for MySQLi, though. I'm a PDO guy.
To make your filters more dynamic, register them in the database, like that:
You can create a model_filters table (in mysql for example):
drop table if exists model_filters;
create table model_filters (
id int not null auto_increment primary key,
name varchar(80) not null,
model varchar(80) not null,
condition varchar(40) not null,
created datetime,
modified datetime,
active boolean not null default 1,
index model_filters (name)
);
So, create some filters, for specific model:
INSERT INTO model_filters VALUES
('Age Above' , 'user' ,'age <= %filter'),
('Age Below' , 'user' ,'age >= %filter'),
('City' , 'user' ,'city ="%filter"'),
('Gender' , 'user' ,'gender = "%filter"');
Then, get the filters based in your model:
SELECT id, name FROM model_filters WHERE model = 'user' AND active = 1
Iterate this values and generate a filters <select>:
<select name="filters" id="filters">
<option value="1">Age Above</option>
<option value="2">Age Below</option>
<option value="3">City</option>
<option value="4">Gender</option>
</select>
<input type="text" name="value" id="value">
And, you get this information, search for selected filter, and then execute your query
<?php
// I'm using PDO
$statment = $pdo->prepare("SELECT * FROM model_filters WHERE id = :id");
$statment->bindValue(':id', $_POST['filters']);
$status = $statment->execute();
$result = null;
if ($status == true) {
$result = $statment->fetchAll(PDO::FETCH_ASSOC);
}
if ($result == null) {
// ERROR!
}
Now, organize the values
/*
$result['condition'] is equal (for example): "age <= %filter"
After replace is = "age <= :filter"
Obs.: replace for whatever you want, for example: ":filtername, :value, :whatever"
*/
$condition = str_replace('%filter', ':filter', $result['condition']);
$statment = $pdo->prepare("SELECT * FROM Users1 WHERE $condition");
$statment->bindValue(':filter', $_POST['value']);
$status = $statment->execute();
$result = null;
if ($status == true) {
$result = $statment->fetchAll(PDO::FETCH_ASSOC);
}
Get $result, sent for your view, and iterate the filtered users.
Done!
I have a server list, and first of all I want to order the servers by the most online users,
but in case that there is a server that is currently in progress + has the most players online at the moment, I want to ignore it.
Basically order by PLAYERS COUNT + status = available, but it doesn't work?
$query = $this->controller->db->fetch("argonite_servers", null, null, "server_status = 'Available', server_players");
And this is my method:
public function fetch($table, array $criteria = null, $limit = null, $order = null)
{
// The query base
$query = "SELECT * FROM $table";
// Start checking
if ($criteria) {
$query .= ' WHERE ' . implode(' AND ', array_map(function($column) {
return "$column = ?";
}, array_keys($criteria)));
}
// limit
if ($limit)
{
$query .= " LIMIT ". $limit;
}
//order
if ($order)
{
$query .= " ORDER BY ".$order." DESC";
}
$check = $this->pdo->prepare($query) or die('An error has occurred with the following message:' . $query);
if ($criteria)
$check->execute(array_values($criteria));
else
$check->execute();
return $check;
}
Why won't it display all servers whom are available + has the most players at the top?
Right now, my table shows this:
(source: gyazo.com)
;
What did I do wrong?
You're where clause is probably select * from argonite_servers where server_status = 'Available' order by server_players desc; It looks like you've merged your order and criteria clauses in your method call instead of keeping them separate.
So instead of
$query = $this->controller->db->fetch("argonite_servers", null, null, "server_status = 'Available', server_players");
You might want:
$query = $this->controller->db->fetch("argonite_servers", "server_status ='Available'", null, "server_players");
EDIT:
To keep the 'available' status showing you are lucky that 'Available' is alphabetically sorted ahead of so do this:
$query = $this->controller->db->fetch("argonite_servers", null, null, "server_status ASC, server_players");
I am facing a problem in making a program with mysql and php...
See i want to save my search queries into the database,,
See this example
Stackoverflow searched = > 20 times on date = > 2013-04-26
Stackoverflow searched = > 10 times on date = > 2013-04-27
Stackoverflow searched = > 50 times on date = > 2013-04-28
Formatting does not matter..Actually i want to save my search queries if the date is changed..
If date got matched so should update times + 1
See this code,,
<?php
$keyword = null;
$date = null;
if (!empty($_GET['s'])) {
$keyword = stripslashes($_GET['s']);
$date = date("Y-m-d");
try {
$objDb = new PDO('mysql:dbname=search;charset=UTF-8', 'root', '');
$check = "SELECT *
FROM `search1`
WHERE `keyword` = '$keyword%'
AND `date` = CURDATE() ";
if (!empty($check))
{
$sql ="UPDATE `search1`
SET `times` = `times` + 1
WHERE `keyword` = '$keyword%'
AND `date` = CURDATE()";
}
else
{
$sql = "INSERT INTO `search1` (`keyword`, `date`) VALUES (:keyword, :date)";
$statement = $objDb->prepare($sql);
$statement->execute(array(':keyword' => $keyword, ':date' => $date));
}
} catch(PDOException $e) {
echo $e->getMessage();
}
}
?>
It is not working.. Something is wrong.. Someone can tell me what is wrong.
I can not use primary key.
you can set a unique index on the field date and keyword
ALTER TABLE `search1` ADD UNIQUE (
`keyword` ,
`date`
);
edit: looks like the OP has got it now, but just for completeness, the above query you just run once to add a unique index to the table - note that it won't work if you have rows that have the same values for keyword and date; if you get a 'duplicate value' error you will have to remove rows until the values are unique before trying again.
then the query
INSERT INTO `search1` (`keyword`, `date`, `times`) VALUES (:keyword, :date, 1) ON DUPLICATE KEY UPDATE `times` = `times` + 1
should do the trick :)