Intereting Posts
Мыло PHP – невозможно импортировать схему Javascript onload function alternative Вызов неопределенной функции: simplexml_load_string () Как обрабатывать несколько проектов в CodeIgniter? URL переписать переменную PHP $ _GET Как я могу защитить этот код от SQL Injection? Немного смущен ODBC SQL update Заявление о выпуске, если более 32 000 символов SQLSTATE : Нарушение ограничения целостности: 1452 Невозможно добавить или обновить дочернюю строку: ограничение внешнего ключа не выполняется Предотвращение отправки двойной формы с использованием токенов Server2go с более новыми версиями PHP Как сделать опрос базы данных в реальном времени в MySQL / PHP? Как перетасовать мой массив или список строк более читабельным способом? Как установить обычную общую сумму перед оформлением заказа в magento? Является ли система очереди laravel подходящей для больших проектов? PHP не будет показывать никаких ошибок

Удалить одинарные кавычки из where_in в codeigniter

Я работаю над функцией search . Я создал форму поиска, в которой пользователь может искать приложение на основе Type , ope & Formate .

Я использовал подзапрос в моем запросе соединения, чтобы получить желаемый результат. Я тестировал свой запрос в MySQL Workbench он работает нормально.

Но когда я пробовал тот же запрос в Codeigniter, используя технику построения запросов, я столкнулся с проблемой.

Вот запрос, который отлично работает в workbench:

 SELECT (*) FROM `App` LEFT JOIN `App_type` ON `App_type`.`app_id` = `App`.`id` LEFT JOIN `App_formate` ON `App_formate`.`app_id` = `App`.`id` WHERE `App`.`id` IN(select app_id FROM App_type WHERE type_id in (3,2,6) group by app_id HAVING COUNT(*) = 3) AND `App_formate`.`formate_id` IN('1', '3') AND `jobs`.`ope_min` <= '3' AND `jobs`.`ope_max` >= '3' GROUP BY `jobs`.`id`; 

Это запрос соединения, который я использую:

 $subquery = "select app_id FROM App_type WHERE type_id in ($selected_type) group by app_id HAVING COUNT(*) = $type_count"; $search_app_query = $this->db ->select('*') ->from('App') ->join('App_type', 'App_type.app_id = App.id', 'left outer') ->join('App_formate', 'App_formate.app_id = App.id', 'left outer') ->where_in('App.id',$subquery) //<-- Here is the problem ->where_in('App_formate.formate_id',$data['selected_formates']) ->where('App.ope_min <=',$data['ope_value']) ->where('App.ope_max >=',$data['ope_value']) ->group_by("App.id", "desc") ->get(); 

Пока я отлаживаю эту проблему, она показывает

  I have found the problem is in this part of the query: "WHERE `App`.`id` IN('select app_id FROM App_type WHERE type_id in (3,2,6) group by app_id HAVING COUNT(*) = 3')" 

эта одинарная кавычка в этом подзапросе создает проблему.

То, что я пробовал до сих пор:

Чтобы удалить эту цитату, я попытался

  1. REPLACE($subquery, '''', '')
  2. ->where_in('App.id',trim($subquery,"'"))
  3. $subquery_improved = substr($subquery, 1, -1);

Но все это решение не работает. Они не удаляют одиночную кавычку.

Примечание. Мне известно о $this->db->query() но не хочу этого использовать.

Ваша задача выглядит довольно просто

вместо

 ->where_in('App.id',$subquery) //<-- Here is the problem 

вы можете попробовать следующее

 ->where("App.id IN (".$subquery.")",NULL, false) 

Вы можете найти эту точную информацию в документации Codeigniter здесь (пункт 4 и раздел ниже).

Мой подход был бы чем-то вроде ниже, более общим образом. Я всегда стараюсь следовать шаблону MVC, нарушая функциональность в небольших функциях. Хотя вы не разделили весь свой код, я все равно предлагаю его.

Вы должны изменить мои пользовательские имена для функций, массивов и т. Д., Чтобы он соответствовал вашему коду. Надеюсь, поможет.

Функция модели

 public function getApp_ids($selected_type, $type_count) { $subquery = "select app_id FROM App_type WHERE type_id in ($selected_type) group by app_id HAVING COUNT(*) = $type_count"; $result = $subquery->get(); if($result->num_rows() > 0) //the check here is relevant to your data return $result->result_array(); return false; } 

Функция модели

 public function searchApp($appIds, $data) { //$appIds and $data are parameters to this function. $search_app_query = $this->db ->select('*') ->from('App') ->join('App_type', 'App_type.app_id = App.id', 'left outer') ->join('App_formate', 'App_formate.app_id = App.id', 'left outer') ->where_in('App.id',$appIds) //pass the array of your IDs ->where_in('App_formate.formate_id',$data['selected_formates']) ->where('App.ope_min <=',$data['ope_value']) ->where('App.ope_max >=',$data['ope_value']) ->group_by("App.id", "desc") ->get(); if($search_app_query->num_rows() > 0) //again, the check is yours return $search_app_query->result_array(); return false; } 

В вашем контроллере что-то вроде этого

 public function YOUR_FUNCTION($selected_type, $type_count) { //call this function from model to grab the app_id you want. Don't forget to pass the parameters you sql needs. $appIdsResult = $this->YOUR_MODEL->getApp_ids($selected_type, $type_count); //Manipulate your result in another array, so you can get rid off the indexes and do some checks if you want $appIds = array(); foreach ($appIdsResult as $appId) { array_push($appIds, $appId['app_id']); //Check the index app_id, it is the result from your DB. } //Call searchApp from your model and pass the found $appIds and your $data ofcourse $result = $this->YOUR_MODEL->searchApp($appIds, $data); //In $result will be your answer } 

замените этот код:

 ->where_in('App.id',$subquery) //<-- Here is the problem 

с этим кодом:

 ->where_in("App.id", $subquery, FALSE) 

третий параметр принимает Boolean, чтобы определить, должна ли функция избегать значения и идентификатора или нет. Если установлено значение FALSE, он не использует одиночную кавычку как escape-символ.

Надеюсь это поможет.

РУКОВОДСТВО ПО ЭКСПЛУАТАЦИИ (небезопасно, используйте очень-очень)

 $sql = "SELECT ....[Your Query].....": $query = $this->db->query($sql); if ($query->num_rows() > 0){ // Found }else{ // Not Found } 

// сначала подтвердить, что подзапрос возвращает только один результат, если не изменить подзапрос

 $subquery = "select GROUP_CONCAT(CONCAT(\"'\",app_id,\"'\")) FROM App_type WHERE type_id in ($selected_type) group by app_id HAVING COUNT(*) = $type_count"; $search_app_query = $this->db ->select('*') ->from('App') ->join('App_type', 'App_type.app_id = App.id', 'left outer') ->join('App_formate', 'App_formate.app_id = App.id', 'left outer') ->where_in('App.id',$subquery,false) //<-- pass 3rd parameter as false for removing single quotes ->where_in('App_formate.formate_id',$data['selected_formates']) ->where('App.ope_min <=',$data['ope_value']) ->where('App.ope_max >=',$data['ope_value']) ->group_by("App.id", "desc") ->get(); 

Я думаю, ваш $subquery был рассмотрен как строка параметров, а не как запрос.
Общий синтаксис метода активной записи

 ->where_in('field_name', array() || 'string values'); 

Вы должны быть таким $subquery

 $subquery = $this->db ->select('app_id') ->from('App_type') ->where_in('type_id',array(3,2,6)) ->group_by('app_id') ->having(' COUNT(*) = 3') ->get() ->row() ->app_id; 

Надеюсь, это сработает 🙂

Вместо

 SELECT (*) 

использование

 SELECT * 

Вместо

 WHERE `App`.`id` IN( select app_id FROM App_type WHERE type_id in (3,2,6) group by app_id HAVING COUNT(*) = 3) 

использование

 JOIN ( select app_id FROM App_type WHERE type_id in (3,2,6) group by app_id HAVING COUNT(*) = 3 ) AS x ON x.app_id = App.id 

(Перевод в CodeIgniter оставлен в качестве упражнения для читателя.)

Прежде всего после запроса, поставьте этот код:

echo $ this-> db-> last_query (); exit;

Это напечатает запрос, и у вас будет идея, в чем проблема. Также скопируйте этот запрос и попробуйте запустить его в phpmyadmin.

Также попробуйте этот тип решения, поскольку у вас есть вопросы с одной цитатой:

В подзапросе введите $ type_count, используя одинарные кавычки, т.е. '$ type_count'

 ->where("App.ope_min <='",$data['ope_value']."'") ->where("App.ope_max >='",$data['ope_value']."'") ->group_by("App.id", "desc") ->get(); 

Дайте мне знать, если вы хотите спросить что-то еще.

Просто добавьте третий параметр в оператор where_in. Попробуй это –

 $subquery = "select app_id FROM app_type WHERE type_id in (3,2,6) group by app_id HAVING COUNT(*) = 3"; $search_app_query = $this->db ->select('*') ->from('app') ->join('app_type', 'app_type.app_id = app.id', 'left outer') ->join('app_formate', 'app_formate.app_id = app.id', 'left outer') ->where_in('app.id',$subquery, FALSE) ->where_in('app_formate.formate_id',array(1,3)) ->where('app.ope_min <=',3) ->where('app.ope_max >=',3) ->group_by("app.id", "desc") ->get()->result(); 

Я бы посоветовал вам не вводить sub-запрос непосредственно в состояние, в котором вы также можете иногда иметь нулевой результат. Таким образом, лучший способ – выполнить свой подзапрос отдельно, как это.

 $subdata = $this->db->select("app_id ")->from("App_type ")->where_in("type_id",$selected_type)->group_by(""app_id)->having("COUNT(*) = $type_count")->get()->result_array(); $search_app_query = $this->db ->select('*') ->from('App') ->join('App_type', 'App_type.app_id = App.id', 'left outer') ->join('App_formate', 'App_formate.app_id = App.id', 'left outer'); if(!empty($subdata)) { $this->db->where_in('App.id',$subdata); } $this->db->where_in('App_formate.formate_id',$data['selected_formates']) ->where('App.ope_min <=',$data['ope_value']) ->where('App.ope_max >=',$data['ope_value']) ->group_by("App.id", "desc") ->get(); 

Спасибо всем вам за ваши предложения.

У меня есть способ решить мою проблему, не изменяя мой другой код.

Благодаря пользователю sintakonte-SO его комментарий был ключом к решению этой проблемы.

Решение – это просто изменение одного кода строки, который я раньше хотел.

 $search_app_query = $this->db ->select('*') ->from('App') ->join('App_type', 'App_type.app_id = App.id', 'left outer') ->join('App_formate', 'App_formate.app_id = App.id', 'left outer') // This is what he suggested me to change and it works. ->where('App.id IN('.$subquery.')') ->where_in('App_formate.formate_id',$data['selected_formates']) ->where('App.ope_min <=',$data['ope_value']) ->where('App.ope_max >=',$data['ope_value']) ->group_by("App.id", "desc") ->get(); 

Большое спасибо пользователю sintakonte-SO снова.