Force not escape query builder CI 3.1.8 - codeigniter

I wrote a query with codeigniter, and need to unescape subquery in from() method. I have a complex query, here I simplify for you
$this->db->from("(SELECT * FROM acme WHERE CONCAT(',', RTRIM(rule), ',') LIKE '%,PER_UNIT,%') AS acme_filtered")
become:
SELECT * FROM (SELECT * FROM acme WHERE CONCAT(',', RTRIM(rule), ',') LIKE '%,`PER_UNIT`,%') AS acme_filtered
the part LIKE '%,PER_UNIT,%' turns into
LIKE '%,PER_UNIT,%'
data cannot be found because additional character (`) wraps the string. How to remove this character so the query turn right?

You could do this, but I don't know the implications of it, as it defeats the escaping system.
Use it with care!
$this->db->from("(SELECT * FROM acme WHERE CONCAT(',', RTRIM(rule), ',') LIKE '%,PER_UNIT,%') AS acme_filtered");
// the rest of your "complex query" code here
$query = $this->db->get_compiled_select();
$query = str_replace('%, `', '%,', $query);
$query = str_replace('`, %', ',%', $query);
$result = $this->db->query($query);

Related

Is it safe to use DB :: select and others in Laravel?

Queries are not always simple, and sometimes I need to create a pure SQL query, the query builder also does not fit.
При использовании DB::select, подготовливаются ли
переменные, которые подставлены в запрос?
Will there be a sql injection in this case?
$mastersInCity = DB::select('SELECT
master_user.master_id,
masters.specialization,
category_letter_master.category_letter_id AS master_letter,
COUNT(*) AS count_in_city
FROM master_user
LEFT JOIN masters ON master_user.master_id = masters.id
LEFT JOIN category_letter_master ON category_letter_master.master_id = master_user.master_id
WHERE ' . $chooiseId . ' = ' . $cityId . ' GROUP
BY master_user.master_id, master_letter');
Or, in this case, it is better to use PDO directly, so as to manually prepare the request yourself, is it possible?
$mastersInCity = DB::select('SELECT
master_user.master_id,
masters.specialization,
category_letter_master.category_letter_id AS master_letter,
COUNT(*) AS count_in_city
FROM master_user
LEFT JOIN masters ON master_user.master_id = masters.id
LEFT JOIN category_letter_master ON category_letter_master.master_id = master_user.master_id
WHERE ? = ? GROUP
BY master_user.master_id, master_letter', [$chooiseId, $cityId]);
This is equivalent to a prepared statement.
Docs: https://laravel.com/docs/5.7/database#running-queries
Edit: I am sure this can be done with eloquent simply, there is nothing too complex here. Something like:
MasterUser::with(['master', 'master_letter'])->withCount()->where($chooiseId, $cityId)->get()

Arithmetic operations in select with CodeIgniter

I´m triying to do an arithmetic operation but i always get error.
This is the query:
public function getAllModifiers($condition)
{
$this->db->select('DM.id AS modifier_id, DM.name, minimum, maximum');
$this->db->select('DMI.id AS item_id, DMI.name AS item_name, `DMI.price * 1.1` AS item_price');
$this->db->from('dishes_modifiers DM');
$this->db->join('dishes_modifiers_items DMI', 'DMI.modifier_id = DM.id', 'left');
$this->db->where($condition);
return $this->db->get()->result();
}
How can i get the item_price * 1.1?
Thanks.
The backticks are used to escape object names (e.g., columns names). Any mathematical operation should be outside this escaping:
$this->db->select(`DMI.price` * 1.1 AS item_price');
# Here -----------^---------^
Check this:
$this->db->where($condition);
This one not checking the data with the database values.
You can use this in where condition
(DMI.price *1.1) > DMI.price *1.1

Can not get the url parameter in PHP

I am trying to get URL parameter in SQL, but nothing happens.
Here is my URL:
http://localhost/webshop/imagegallery.php?categori=necklace
Here is my SQL query:
$sql = 'SELECT count(productid) FROM products where productcategori=".$_GET["categori"]"';
What am I doing wrong?
Have a look at this query, too:
$sql = 'select * from products join ids on products.productid=ids.productid join photos on photos.photosid=ids.photoid where products.productcategori='".$_GET["kategori"]."' && ids.photonumber=1 ORDER BY products.productid DESC $limit';
First of all, your quotation marks seem to be the problem. Try changing your query line to this:
$sql = "SELECT count(productid) FROM products where productcategori='".$_GET["categori"]."'";
Further, you should never insert variables into a SQL query like this. Never.
The reason is that like this, your system is vulnerable for SQL injections.
Instead consider using PDO. This SO question has a nice answer on how to do it correctly.
Using that answer, this is some example code regarding the last part of your question. Note that I replaced all variables in your query string by PDO placeholders.
<?php
$pdo = new PDO('mysql:dbname=mydatabase;host=127.0.0.1;charset=utf8', 'username', 'password');
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "SELECT * FROM products JOIN ids ON products.productid=ids.productid JOIN photos ON photos.photosid=ids.photoid WHERE products.productcategori=:categori && ids.photonumber=1 ORDER BY products.productid DESC LIMIT :limit_min , :limit_max";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':categori', $_GET['categori']);
$stmt->bindParam(':limit_min', ($pagenum - 1) * $page_rows, PDO::PARAM_INT);
$stmt->bindParam(':limit_max', $page_rows, PDO::PARAM_INT);
$stmt->execute();
foreach($stmt as $row) {
// do something with $row
}
?>

CodeIgniter like query with single quote in search string

I have been working on this for like more than 4 hours. I have select query using active record I am doing: $this->db->like ('items.name',$search);
everything works fine but whenever there is single quote (') in the $search string it gives this error:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 's%' OR default_items.short LIKE 'faith\'s%' LIMIT 5' at line 5
I have just checked now that it is adding double back slashes \\ instead of single in my active record for LIKE query. I tried in MySQL bt removing one slash and it is working.
My code:
$q = "faith's";
$query = $this->db->select('items_categories.slug as category_slug, items_categories.name as cat_name, items.name, items.price_value, items.cover_photo, items.slug');
$query->select('default_items.short as short',false);
$query->select('date(default_items.date_created) as date_created',false);
$query->join('items_categories','items_categories.id=items.root_id','inner');
$query->join('users','items.company_id=users.id','inner');
$query->like('items.name',$q);
$query->or_like('items.short',$q);
$query->limit(5);
$result = $query->get($this->_table);
$both_prod_results = $result->result();
I am using pyrocms 2.x.
You can try the following code maybe it can help you, but you have to add \ before every' in your requests :
$value = "faith\'s";
$sql_request = "`short` LIKE '%". $value ."%'";
$query = $this->db
->select('*')
->where($sql_request, null, false)
->get('default_items');
$result = $query->result();
dump($result);
i think i need to answer my own question.
Well this is a hack(don't think if it is secure)
I have patched my MYSQLI Driver:
i have replaced this:
return str_replace(array($this->_like_escape_chr, '%', '_'),
array($this->_like_escape_chr.$this->_like_escape_chr, $this->_like_escape_chr.'%', $this->_like_escape_chr.'_'),
$str);
with this:
return str_replace(array($this->_like_escape_chr, '%', '_'),
array($this->_like_escape_chr, $this->_like_escape_chr.'%', $this->_like_escape_chr.'_'),
$str);
it was adding extra slash. and also don't think it will allow sql injections etc anything.
if anyone knows this is right then please comment.
Thanks
Umair

How to order by count in Doctrine 2?

I'm trying to group my entity by a field (year) and do a count of it.
Code:
public function countYear()
{
$qb = $this->getEntityManager()->createQueryBuilder();
$qb->select('b.year, COUNT(b.id)')
->from('\My\Entity\Album', 'b')
->where('b.year IS NOT NULL')
->addOrderBy('sclr1', 'DESC')
->addGroupBy('b.year');
$query = $qb->getQuery();
die($query->getSQL());
$result = $query->execute();
//die(print_r($result));
return $result;
}
I can't seem to say COUNT(b.id) AS count as it gives an error, and
I do not know what to use as the addOrderby(???, 'DESC') value?
There are many bugs and workarounds required to achieve order by expressions as of v2.3.0 or below:
The order by clause does not support expressions, but you can add a field with the expression to the select and order by it. So it's worth repeating that Tjorriemorrie's own solution actually works:
$qb->select('b.year, COUNT(b.id) AS mycount')
->from('\My\Entity\Album', 'b')
->where('b.year IS NOT NULL')
->orderBy('mycount', 'DESC')
->groupBy('b.year');
Doctrine chokes on equality (e.g. =, LIKE, IS NULL) in the select expression. For those cases the only solution I have found is to use a subselect or self-join:
$qb->select('b, (SELECT count(t.id) FROM \My\Entity\Album AS t '.
'WHERE t.id=b.id AND b.title LIKE :search) AS isTitleMatch')
->from('\My\Entity\Album', 'b')
->where('b.title LIKE :search')
->andWhere('b.description LIKE :search')
->orderBy('isTitleMatch', 'DESC');
To suppress the additional field from the result, you can declare it AS HIDDEN. This way you can use it in the order by without having it in the result.
$qb->select('b.year, COUNT(b.id) AS HIDDEN mycount')
->from('\My\Entity\Album', 'b')
->where('b.year IS NOT NULL')
->orderBy('mycount', 'DESC')
->groupBy('b.year');
what is the error you get when using COUNT(b.id) AS count? it might be because count is a reserved word. try COUNT(b.id) AS idCount, or similar.
alternatively, try $qb->addOrderby('COUNT(b.id)', 'DESC');.
what is your database system (mysql, postgresql, ...)?
If you want your Repository method to return an Entity you cannot use ->select(), but you can use ->addSelect() with a hidden select.
$qb = $this->createQueryBuilder('q')
->addSelect('COUNT(q.id) AS HIDDEN counter')
->orderBy('counter');
$result = $qb->getQuery()->getResult();
$result will be an entity class object.
Please try this code for ci 2 + doctrine 2
$where = " ";
$order_by = " ";
$row = $this->doctrine->em->createQuery("select a from company_group\models\Post a "
.$where." ".$order_by."")
->setMaxResults($data['limit'])
->setFirstResult($data['offset'])
->getResult();`

Resources