I have a query that is working but is does not have binded values:
$this->_db->query("SELECT * from posts WHERE post_title LIKE '%$this->search_keywords%' OR post_content LIKE '%$this->search_keywords%' LIMIT 100");
$this->rows_results_found = $this->_db->resultset();
$this->results_found_num = sizeof($this->rows_results_found);
I am rewriting it to this one but with no luck:
$this->_db->query('SELECT * from posts WHERE post_title LIKE :search_keywords OR post_content LIKE :search_keywords LIMIT 100');
$this->_db->bind(':search_keywords', '%$this->search_keywords%');
$this->rows_results_found = $this->_db->resultset();
$this->results_found_num = sizeof($this->rows_results_found);
$this->results_found_num appears always to be an empty array.
This is what I have in the resultset() (It is from another outer class):
public function resultset() {
$this->execute();
return $this->stmt->fetchAll(PDO::FETCH_ASSOC);
}
What I am missing here?
Thank you in advance!
Assuming you have a valid connection adjust your function to the following:
public function get_posts($conn) {
$query = 'SELECT *
FROM posts
WHERE post_title LIKE :search_keywords1 OR
post_content LIKE :search_keywords2 LIMIT 100';
$stmt = $conn->prepare($query);
$stmt->bindValue(':search_keywords1', '%'.$this->search_keywords.'%');
$stmt->bindValue(':search_keywords2', '%'.$this->search_keywords.'%');
$stmt->execute();
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
Usage:
$posts = $this->_db->get_posts($conn);
//var_dump($post)
$this->rows_results_found = count($post);
Related
I am new in oop and I am trying to change a sql query into 3 chained method and use like this:
$mtag = $mtag->allTags()->orderBy()->lastThree();
public function allTags()
{
$sql = "SELECT tag_id FROM posts_tags ";
$sql .= "GROUP BY tag_id ";
$sql .= "ORDER BY COUNT(*) DESC LIMIT 3 ";
$res = self::builder($sql);
return $res;
}
i want to use each $sql in to a separate chain method .
how can i do this?
i have tried this but it doesnt work
public function allTags()
{
$sql = "SELECT tag_id FROM posts_tags ";
self::builder($sql);
return $this;
}
public function orderBy()
{
$sql = "GROUP BY tag_id ";
self::builder($sql);
return $this;
}
public function lastThree()
{
$sql = "ORDER BY COUNT(*) DESC LIMIT 3 ";
self::builder($sql);
return $this;
}
my builder method looks like this
public function builder(string $sql)
{
$stmt = $this->database->prepare($sql);
$stmt->execute();
if (!$stmt) {
throw new Exception("Query failed . . .");
}
return $stmt;
}
The problem is that the self::builder($sql); method directly prepares the sql statement, instead of waiting for it to be completely constructed:
$mtag = $mtag
/*
the first self::builder($sql) is called,
prepares the statement without the order and group by
*/
->allTags()
/*
the second self::builder($sql) is called from orderBy, prepares "GROUP BY tag_id "
probably a syntax error is hidden here
*/
->orderBy()
/*
the third self::builder($sql) is called from lastThree
it tries to prepare "ORDER BY COUNT(*) DESC LIMIT 3 "
a syntax error is probably hidden here too
*/
->lastThree();
The statement is prepared over and over again. You can avoid this by doing, in that order
defining the statement with all its chained variants
calling a method to fetch data, preparing the statement composed from the various chained method calls.
$stmt = $mtag->allTags()->orderBy()->lastThree();
$result = $stmt->resolve();
where $stmt = $this->database->prepare($sql); only happens in the resolve method.
you have error in return code.
Change to that code!
public function lastThree()
{
$sql = "ORDER BY COUNT(*) DESC LIMIT 3 ";
$res = self::builder($sql);
return $res;
}
How I use order by (name) in this code to get result in asc order?
This is the piece of code:
function getRecordByID($id)
{
$this->db->select($this->tbl_area_menu.'.*,'.$this->tbl_users.'.firstname as created_by,'.$this->tbl_page.'.name as page_name,'.$this->tbl_page.'.slug as page_slug,'.$this->tbl_page.'.template_directory,'.$this->tbl_directory.'.slug as directory_slug');
$this->db->where($this->tbl_area_menu.'.id',$id);
$this->db->join($this->tbl_users,$this->tbl_users.'.id = '.$this->tbl_area_menu.'.created_by','left');
$this->db->join($this->tbl_page,$this->tbl_page.'.id = '.$this->tbl_area_menu.'.page_id','left');
$this->db->join($this->tbl_directory,$this->tbl_directory.'.id = '.$this->tbl_page.'.template_directory','left');
$query = $this->db->get($this->tbl_area_menu);
//echo $this->db->last_query();
$record = $query->row();
return $record;
}
Looks like you are using Query Builder. If that is the case, after all the joins add $this->db->order_by('name', 'ASC');
I have two put two condition in the result of a sql query result for the below function:
Table projects has two columns a_name and b_name and I want to exclude result in which b_name has value = xxxxx and value in a_name and b_name are same.
Below is currently used:
public function search_project_name($term)
{
$params = array( ':term' => $term);
$sql = "SELECT * FROM projects WHERE project_name like '%$term%'ORDER BY projects.create_date DESC $limit";
$stmt = parent::query($sql, $params);
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) :
$result[]=$row;
endwhile;
return $result;
}
You could add these condition with a not operator:
SELECT *
FROM projects
WHERE a_name like '%$term%' AND
NOT (a_name = 'xxxx' and a_name = b_name)
Problem part is $term in query so replace $term with :term try updated code:
public function search_project_name($term){
$params = array(
':term'=>$term);
$sql = "SELECT * FROM projects WHERE project_name like '%:term%'ORDER BY projects.create_date DESC $limit";
$stmt = parent::query($sql, $params);
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) :
$result[] = $row;
endwhile;
return $result;
}
One more missing parameter is $limit you used in query but not passed to function?
With $limit as 2nd parameter default set to 10 rows:
public function search_project_name($term, $limit = 10){
$params = array(
':term'=>$term);
$sql = "SELECT * FROM projects WHERE project_name like '%:term%'ORDER BY projects.create_date DESC $limit";
$stmt = parent::query($sql, $params);
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) :
$result[] = $row;
endwhile;
return $result;
}
In PHP, I use a lot of one liners like:
Fetch value:
$sql->query("SELECT ID FROM table WHERE condition = 1")->fetch_object()->ID;
Fetch row:
$sql->query("SELECT * FROM table WHERE condition = 1")->fetch_assoc();
Fetch rows:
$sql->query("SELECT * FROM table WHERE condition > 1")->fetch_all(MYSQLI_ASSOC);
Insert row:
$sql->query("INSERT INTO table(`row1`,`row2`) VALUES('".$data1."','".$data2."')");
Delete row:
$sql->query("DELETE FROM table WHERE condition = 1");
Are there also beautiful one liners for prepared statements?
This fails:
$sql->prepare("SELECT ID FROM table WHERE condition = ?")->bind_param("i", $a=1)->execute()->fetch_object()->ID;
This works:
$query = $sql->prepare("SELECT ID FROM table WHERE condition = ?");
$query->bind_param("i", $a=1);
$query->execute();
$query->get_result()->fetch_object()->ID;
Directly - there is no way. But you may use a simple overlay class which will allow you to do so.
class PrepareOverlay {
private $stmt;
private $lastResult = null;
public function __construct(PDOStatement $stmt) {
$this->stmt = $stmt;
}
public function __call($name, $arguments) {
$this->lastResult = call_user_func_array([$this->stmt, $name], $arguments);
return is_bool($this->lastResult) ? $this : $this->lastResult;
}
public function getLastResult() {
return $this->lastResult;
}
public static function prepare($sql, $query) {
return new self($sql->prepare($query));
}
}
And use it like this:
PrepareOverlay::prepare($sql, 'SELECT * FROM table WHERE cond = ?')->bindParam('i', $a=1)->execute()->fetchObject()->ID;
Although you will need some phpdoc to make code completion work.
if you consider using a framework like codeigniter you will be able to enjoy the Active record class, and you will be able to use something elegant like those lines :
$query = $this->db->get('mytable');
// Produces: SELECT * FROM mytable
or
$query = $this->db->get_where('mytable', array('id' => $id), $limit, $offset);
or
$this->db->select('*');
$this->db->from('blogs');
$this->db->join('comments', 'comments.id = blogs.id');
$query = $this->db->get();
// Produces:
// SELECT * FROM blogs
// JOIN comments ON comments.id = blogs.id
you can also use chaining like this
$this->db->select('title')->from('mytable')->where('id', $id)->limit(10, 20);
$query = $this->db->get();
or
echo $this->db->count_all('my_table');
// Produces an integer, like 25
or
$this->db->delete('mytable', array('id' => $id));
// Produces:
// DELETE FROM mytable
// WHERE id = $id
and much more ... take a look at the documentation for a full documentation about active record
cheers !
I want to store mysqli query results to array.
My code so far looks like this:
function get_nearby_users($Id, $MaxDistance, $RowLimit, $RowLimitOffset)
{
try
{
$query = "SELECT
others.*,
Distance(me.Latitude, me.Longitude, others.Latitude, others.Longitude) as Distance
from
Users me
join
Users others
where
me.Id = ?
and
others.Id != ?
having Distance < ?
limit ?,?
";
$stmt = $this->link->prepare($query);
$stmt->bind_param('iiiii', $Id, $Id, $MaxDistance, $RowLimitOffset, $RowLimit);
$stmt->execute();
// how to fill $rows_array?
}
catch(Exception $exc)
{
// ...
}
return $rows_array;
}
How can I put my results to array when my SQL contains something like "SELECT *"?
All tutorials with parametrized queries use bind_result function, but I don't want to create variables for all fields and bind them. There is no other way?
You do not need to use bind_result to store the record set.
Just use fetchAll() to store result set rows as an array.
$rows_array = $stmt->fetchAll();
I have modified your code. Use this:
function get_nearby_users($Id, $MaxDistance, $RowLimit, $RowLimitOffset)
{
try
{
$query = "SELECT
others.*,
Distance(me.Latitude, me.Longitude, others.Latitude, others.Longitude) as Distance
from
Users me
join
Users others
where
me.Id = ?
and
others.Id != ?
having Distance < ?
limit ?,?
";
$stmt = $this->link->prepare($query);
$stmt->bind_param('iiiii', $Id, $Id, $MaxDistance, $RowLimitOffset, $RowLimit);
$stmt->execute();
$rows_array = $stmt->fetchAll(); // store result set rows as an array
}
catch(Exception $exc)
{
// ...
}
return $rows_array;
}