i try to search in laravel with ajax . i post two variables but my query doesn't work well this is my code
public function search(Request $request){
$tag= $request->tag;
$selected = $request->selected;
$selected = "'" . implode ( "','", $selected ) . "'";
$output = '';
if ($tag != '')
{
$data= DB::table('tags')->where('name','like','%'.$tag.'%')->whereNotIn('name',[$selected])->orderBy('id', 'desc')->get();
}
$total_row = $data->count();
if($total_row > 0)
{
foreach($data as $row)
{
$output .= '<a>'.$row->tag_name.'</a>';
}
}
return Response()->json($output);
}
**my problem is $selected i converted it to string = 'one','two','three' but doesn't work **
Your $output is not an array but you convert it to json response?
and Response()->json() is not a helper you should use response()->json(). I don't have any idea about your query but change top tips and check results.
One day I'm on this problem and I cant find the solution.
My goal is to return a list of links from an ID (the father). So I want all his childs.
But in the view, I only have on result (the 1st one...).
I have in my controller :
$data['list_link'] = $this->menuManager->list_link();
In my Model :
function list_link($fatherid=0){
$r = array();
$sSQL = 'SELECT * FROM categories WHERE fatherid = ' . $fatherid . ' AND siteid = ' . MY_SITEID_DEFAULT . ' ORDER BY name';
$query = $this->db->query($sSQL);
// stock results in array
$r[] = $query->result_array();
foreach ($query->result() as $row) {
// let's find the childs
$this->list_link($row->id,$loop);
}
return $r;
}
If I "for each" the $r here, all looks good.
So, $data['list_link'] shoud now have all the rows.
In my view :
foreach ($list_link as $link){
foreach ($link as $row){
echo $row['name'];
}
}
But, I only have the first links (first childs), not the other one. Any help would be greatly appreciated as I'm on that problem for days...
You're not storing any values in the recursive calls (though I'm still not sure you'd get what you expect). You'd need to populate $r with each function call:
$r[] = $this->list_link($row->id,$loop);
However, either I missed something or you're overcomplicating things, but I think you could simply return the result array and use it:
function list_link($fatherid=0,$loop=0){
$sSQL = 'SELECT * FROM categories WHERE fatherid = ' . $fatherid . ' AND siteid = ' . MY_SITEID_DEFAULT . ' ORDER BY name';
$query = $this->db->query($sSQL);
return $query->result_array();
}
UPDATE
Your latest version still doesn't collect the data from recursive calls, here is the full function, see if it works:
function list_link($fatherid=0){
$r = array();
$sSQL = 'SELECT * FROM categories WHERE fatherid = ' . $fatherid . ' AND siteid = ' . MY_SITEID_DEFAULT . ' ORDER BY name';
$query = $this->db->query($sSQL);
$result = $query->result_array();
// stock results in array
$r[$fatherid] = $result;
foreach ($result as $row) {
// let's find the children
$r[$fatherid][$row['id']] = $this->list_link($row['id']);
}
return $r;
}
Note that I've added $r[$fatherid][$row['id']] so the end result should be an array with a branching structure. If you don't want that, just do $r[] instead.
I have the following PHP, that needs to take a list of article ids and run it through a function to get them all from the database.
I am very much a beginner in PHP so far I have:
list($slide1, $slide2, $slide3, $slide4, $slide5) = explode(" ", $params->get('id'));
$a = array(
$item => $slide1,
"two" => $slide2,
// "three" => $slide3,
// "four" => $slide4,
// "five" => $slide5
);
foreach ($a as $k) {
$args['id'] = $k;
$item = ModArticleSlider::getArticles($args);
}
and the class:
class ModArticleSlider {
public function getArticles($args){
$db = &JFactory::getDBO();
$item = "";
$id = $args['id'];
if($id > 0){
$query = "select * ";
$query .= "FROM #__content WHERE id =".$id." AND state=1 " ;
//echo $query;
$db->setQuery($query);
$item = $db->loadObject();
}
return $item;
}
}
How would i get it so that instead of specifying $item to have it almost dynamic so that i can get all the selected articles and place them in different variables.. or would i have to place them in a array?
Any Advice/Answers Greatly Appreciated.
Another approach, and possibly more performant as it would require only one database query (versus one for each article), would be to use http://docs.joomla.org/JDatabase::loadObjectList
So, you could instead pass an array of your articles ids as $ids to your class like:
public function getArticles($ids){
if ($ids) {
$db = JFactory::getDbo();
$query = "SELECT * FROM #__content WHERE id IN (" . implode(',', $id) . ") AND state=1 " ;
$db->setQuery($query);
$rows = $db->loadObjectList();
return $rows;
}
return FALSE;
}
$rows is returned as an array so you can then process it as needed.
i am also beginner of PHP.
Please Try this:
foreach ($a as $k => $val) {
$args = $val;
$item[] = ModArticleSlider::getArticles($args);
var_dump($item);
}
in your class
simply
$id = $args;
i hope it will help you!
Store the articles into an array, you can try this:
$slides = explode(" ", $params->get('id'));
$articleArray = array();
foreach($slides as $slide) {
$articleArray[] = ModArticleSlider::getArticles($slide);
}
var_dump($articleArray);
Is there any way to make the below-given code reusable for different tables, e.g. using foreach? So, how to send and use arrays of column names and values? Any example is highly appreciated.
<?php
include_once 'include/DatabaseConnector.php';
if(isset($_POST['flightNum'])) {
$flightNum=$_POST['flightNum'];
$from=$_POST['from'];
$STADate=$_POST['STADate'];
$query = 'UPDATE flightschedule
SET frm="'.$from.'",STADate="'.$STADate.'"
WHERE flightNum="'.$flightNum.'"';
DatabaseConnector::ExecuteQuery($query);
echo '1';
} else {
echo '0';
}
?>
UPDATE: What if I don't know column names apriori? How to create flexible UPDATE statement?
you can convert your code into a reusable function. for example.
function updateDB($tableName, $flightNum, $from, $STADate) {
include_once 'include/DatabaseConnector.php';
$query = 'UPDATE ' . $tableName
SET frm="'.$from.'",STADate="'.$STADate.'"
WHERE flightNum="'.$flightNum.'"';
$execute = DatabaseConnector::ExecuteQuery($query);
return $execute;
}
and to use it
if(isset($_POST['flightNum']) {
$update = updateDB('flightschedule', $_POST['flightNum'], $_POST['from'], $_POST['STADate']);
echo $update;
}
Update:
I want to send an array of column names to the function 'updateDB'.
Let's say these are column names for SET and WHERE parts of UPDATE
statement. And then I could use FOREACH, but I need some example for
this.
this is how you can do it.
function updateDB($tableName, $columns, $where) {
//do some validation here to check if proper data is being passed like
if(!isarray($columns)) {
throw new Exception('argument two $columns should be an associative array');
}
include_once 'include/DatabaseConnector.php';
$query = 'UPDATE ' . $tableName;
foreach($columns as $column => $data) {
$query .= ' SET ' . $column . ' = ' . $data . ', ';
}
//remove last comma from the update query string
$query = substr($query, 0, -1);
$query .= ' WHERE ' . $where['column'] . ' = ' . $where['value'];
$execute = DatabaseConnector::ExecuteQuery($query);
return $execute;
}
and to use it.
if(isset($_POST['flightNum']) {
$columns = array(
'frm' => $_POST['frm'],
'STADate' => $_POST['STADate']
);
$where = array(
'column'=> 'flightNum',
'value' => $_POST['flightNum']
);
$update = updateDB('flightschedule', $columns, $where);
echo $update;
}
Something like this should work:
function generateUpdateQuery($table, $fields, $where) {
$updateFields = array();
foreach ($fields as $k => $v) {
$updateFields[] = $k.' = \''.$v.'\'';
}
$sqlQuery = 'UPDATE '.$table.
' SET '.implode(', ', $updateFields).
' WHERE '.implode(' AND ', $where);
return $sqlQuery;
}
echo generateUpdateQuery('table_name',
array(
'field_a' => '10',
'field_b' => 'hello',
'field_c' => 'world'),
array(
'id=12',
'datetime > NOW()')
);
Keep in mind that this is a simple example without any security check. Something like PDO would be recommended.
Moreover, if you're looking for something more robust and flexible you should give a look to a ORM system, like Doctrine
So I'm trying to create a function that generates a SQL query string based on a multi dimensional array.
Example:
function createQueryString($arrayToSelect, $table, $conditionalArray) {
$queryStr = "SELECT ".implode(", ", $arrayToSelect)." FROM ".$table." WHERE ";
$queryStr = $queryStr.implode(" AND ",$conditionalArray); /*NEED HELP HERE*/
return $queryStr;
}
$columnsToSelect = array('ID','username');
$table = 'table';
$conditions = array('lastname'=>'doe','zipcode'=>'12345');
echo createQueryString($columnsToSelect, $table, $conditions); /*will result in incorrect SQL syntax*/
as you can see I need help with the 3rd line as it's currently printing
SELECT ID, username FROM table WHERE
lastname AND zipcode
but it should be printing
SELECT ID, username FROM table WHERE
lastname = 'doe' AND zipcode = '12345'
You're not actually imploding a multidimensional array. $conditions is an associative array.
Just use a foreach loop inside your function createQueryString(). Something like this should work, note it's untested.:
$terms = count($conditionalArray);
foreach ($conditionalArray as $field => $value)
{
$terms--;
$queryStr .= $field . ' = ' . $value;
if ($terms)
{
$queryStr .= ' AND ';
}
}
Note: To prevent SQL injection, the values should be escaped and/or quoted as appropriate/necessary for the DB employed. Don't just copy and paste; think!
function implodeItem(&$item, $key) // Note the &$item
{
$item = $key . "=" . $item;
}
[...]
$conditionals = array(
"foo" => "bar"
);
array_walk($conditionals, "implodeItem");
implode(' AND ', $conditionals);
Untested, but something like this should work. This way you can also check if $item is an array and use IN for those cases.
You will have to write another function to process the $conditionalArray, i.e. processing the $key => $value and handling the types, e.g. applying quotes if they're string.
Are you just dealing with = condition? What about LIKE, <, >?
Forgive me if its not too sexy !
$data = array('name'=>'xzy',
'zip'=>'3432',
'city'=>'NYK',
'state'=>'Alaska');
$x=preg_replace('/^(.*)$/e', ' "$1=\'". $data["$1"]."\'" ',array_flip($data));
$x=implode(' AND ' , $x);
So the output will be sth like :
name='xzy' AND zip='3432' AND city='NYK' AND state='Alaska'
I'd advise against automated conditionals creation.
Your case is too local, while there can be many other operators - LIKE, IN, BETWEEN, <, > etc.
Some logic including several ANDs and ORs.
The best way is manual way.
I am always doing such things this way
if (!empty($_GET['rooms'])) $w[]="rooms='".mesc($_GET['rooms'])."'";
if (!empty($_GET['space'])) $w[]="space='".mesc($_GET['space'])."'";
if (!empty($_GET['max_price'])) $w[]="price < '".mesc($_GET['max_price'])."'";
Though if you still want it with this simple array, just iterate it using
foreach ($conditions as $fieldname => $value)...
and then combine these variables in the way you need. you have 2 options: make another array of this with field='value' pairs and then implode it, or just concatenate, and substr trailing AND at the end.
I use a variation of this:
function implode_assoc($glue,$sep,$arr)
{
if (empty($glue)) {$glue='; ';}
if (empty($sep)) {$sep=' = ';}
if (is_array($arr))
{
foreach ($arr as $k=>$v)
{
$str .= $k.$sep.$v.$glue;
}
return $str;
} else {
return false;
}
};
It's rough but works.
Here is a working version:
//use: implode_assoc($v,"="," / ")
//changed: argument order, when passing to function, and in function
//output: $_FILES array ... name=order_btn.jpg / type=image/jpeg / tmp_name=G:\wamp\tmp\phpBDC9.tmp / error=0 / size=0 /
function implode_assoc($arr,$glue,$sep){
$str = '';
if (empty($glue)) {$glue='; ';}
if (empty($sep)) {$sep=' = ';}
if (is_array($arr))
{
foreach ($arr as $key=>$value)
{
$str .= $key.$glue.$value.$sep;
}
return $str;
} else {
return false;
}
}
I know this is for the case of a pdo mysql type.. but what i do is build pdo wrapper methods, and in this case i do this function that helps to build the string, since we work with keys, there is no possible way to mysql inject, since i know the keys i define / accept manually.
imagine this data:
$data=array(
"name"=>$_GET["name"],
"email"=>$_GET["email"]
);
you defined utils methods...
public static function serialize_type($obj,$mode){
$d2="";
if($mode=="insert"){
$d2.=" (".implode(",",array_keys($obj)).") ";
$d2.=" VALUES(";
foreach ($obj as $key=>$item){$d2.=":".$key.",";}
$d2=rtrim($d2,",").")";}
if($mode=="update"){
foreach ($obj as $key=>$item){$d2.=$key."=:".$key.",";}
}
return rtrim($d2,",");
}
then the query bind array builder ( i could use direct array reference but lets simplify):
public static function bind_build($array){
$query_array=$array;
foreach ($query_array as $key => $value) { $query_array[":".$key] = $query_array[$key]; unset($query_array[$key]); } //auto prepair array for PDO
return $query_array; }
then you execute...
$query ="insert into table_x ".self::serialize_type( $data, "insert" );
$me->statement = #$me->dbh->prepare( $query );
$me->result=$me->statement->execute( self::bind_build($data) );
You could also go for an update easy with...
$query ="update table_x set ".self::serialize_type( $data, "update" )." where id=:id";
$me->statement = #$me->dbh->prepare( $query );
$data["id"]="123"; //add the id
$me->result=$me->statement->execute( self::bind_build($data) );
But the most important part here is the serialize_type function
Try this
function GeraSQL($funcao, $tabela, $chave, $valor, $campos) {
$SQL = '';
if ($funcao == 'UPDATE') :
//Formata SQL UPDATE
$SQL = "UPDATE $tabela SET ";
foreach ($campos as $campo => $valor) :
$SQL .= "$campo = '$valor', ";
endforeach;
$SQL = substr($SQL, 0, -2);
$SQL .= " WHERE $chave = '$valor' ";
elseif ($funcao == 'INSERT') :
//Formata SQL INSERT
$SQL = "INSERT INTO $tabela ";
$SQL .= "(" . implode(", ", array_keys($campos) ) . ")";
$SQL .= " VALUES ('" . implode("', '", $campos) . "')";
endif;
return $SQL;
}
//Use
$data = array('NAME' => 'JOHN', 'EMAIL' => 'J#GMAIL.COM');
GeraSQL('INSERT', 'Customers', 'CustID', 1000, $data);