semantical error when passing an array to the query - php

i have an array with conditions i have already prepared to pass it to the query:
array:
('u.registered = 1','u.active = 0', 'u.gender = M')
when i pass to the query, it works with the number comparison but not with the varchar which is M. The error appears in "gender", it says it is a semantical error. I assume is because i am not using expr()->literal('M'), but i can't do this because the query is "already built"..
Is there an alternative way so i don't have to code all over again?
this is the code:
public function customR($data){
// var_dump($data);die();
$this->qb = $this->em->createQueryBuilder();
$andX = $this->qb->expr()->andX();
$this->qb->select('u')
->from('models\User','u');
foreach ($data as $value){
$andX->add($value);
}
$this->qb->add('where', $andX);
$query = $this->qb->getQuery();
// var_dump($query);die();
$obj = $query->getResult();
var_dump($obj);die();
if (!empty($obj)){
return $obj;
return false;
}
}

I found no way to do this, so i just changed it a little bit.
I send an array with some elements, just to have the reference of what exists and what doesn't.
So, in my Data Service I've created a function and a snippet of that function to solutionate my question was to do this:
if($key == 'gender'){
foreach($value as $key=>&$v){
$condition = ('u.gender = '. $this->qb->expr()->literal($v));
$orX->add($condition);
}
}

Related

Argument 1 passed to Illuminate\Database\Grammar::parameterize() must be of the type array, string given

It clear shown that $file_ids is array type but still getting this error, and I used different function to know the data type of variable like gettype() it also return array.please help me to get rid from this headache.
Thanks in advance.
public function getFilesForLink(Request $request)
{
$file_ids = array();
$ids = $request->input('selected_file');
if (count($ids) > 0) {
foreach ($ids as $id => $value) {
$file_ids[] = base64_decode($value);
}
}
$link_id = $this->makeDownloadLink($file_ids, $_POST['password']);
if ($_POST['via'] == 'Email') {
$files = File::find($file_ids);
foreach ($files as $name) {
$files_name[] = $name->name;
}
$this->sendEmail($files_name, $link_id, $_POST['recipient'],
$_POST['subject'], $_POST['body']);
}
In one place you are using $file_ids and in others $files_ids so make sure you are using same variable.
In addition are you sure you have valid values in $file_ids array?
Looking at the comment the problem is:
$downloadLink->file_ids = $file_ids;
inside makeDownloadLink method.
You are doing something like this:
if (count($file_ids) > 1) {
$downloadLink->file_ids = implode(',', $file_ids);
}
$downloadLink->file_ids = $file_ids;
and this will fail when $file_ids is array. You should probably add else here like so:
if (count($file_ids) > 1) {
$downloadLink->file_ids = implode(',', $file_ids);
}
else {
$downloadLink->file_ids = $file_ids;
}
check this pieces of code
$files = File::get($file_ids);
replace get() with find()
$files = File::find($file_ids);

Undefined Offset 0: Laravel

I HAVE already read through the other similar questions on stackoverflow and none of them have helped me to find a solution.
This has be completely confused, what was once working has randomly broken and I have no idea whats wrong, the error doesn't seem logical to me i'll show you what i mean.
public function nGetOverviewAccounts()
{
$results = Account::where('archive', '=', false)->select('id', 'display_name', 'server_ip_address', 'server_password', 'status_type_id', 'account_type_id')->get()->toArray();
$index = 0;
$accounts = [];
foreach($results as $result)
{
$accountType = AccountType::where('id', $result['account_type_id'])->select('name')->get()->toArray();
$statusType = StatusType::where('id', $result['status_type_id'])->select('name')->get()->toArray();
return $accountType[0]['name']; //this works
$accounts[$index]['account_type'] = $accountType[0]['name']; //this doesnt..
$accounts[$index]['status_type'] = $statusType[0]['name'];
$index++;
}
return $accounts;
}
That code is right next to each other in the function. The array $accountType looks like this.
0:{name: "Google"}
Which shows that it has an index of 0 but its not working.
EDIT: PLEASE READ
Im going to clear something up i seems to have put it across wrongly to you guys, the return statement is added by me AFTER i get the undefined index error i only added it to the code to show that it works when i return it but when i try to assign its value to another variable (without the return statement) i get the undefined index error.
Try this:
public function nGetOverviewAccounts()
{
$results = Account::where('archive', '=', false)->select('id', 'display_name', 'server_ip_address', 'server_password', 'status_type_id', 'account_type_id')->get()->toArray();
$accounts = [];
foreach($results as $key => $result)
{
$accountType = AccountType::where('id', $result['account_type_id'])->select('name')->get()->toArray();
$statusType = StatusType::where('id', $result['status_type_id'])->select('name')->get()->toArray();
if(!empty( $accountType[0]['name'])) && !empty( $statusType[0]['name'])){
$accounts[$key]['account_type'] = $accountType[0]['name']; //this doesnt..
$accounts[$key]['status_type'] = $statusType[0]['name'];
}
}
return $accounts;
}
Also if you want the first key of $accountType and $statusType then you can use first() instead of get(). If your keys are different then you can use the $index
Adding some checks never hurt anyone:
public function nGetOverviewAccounts() {
$results = Account::where('archive', '=', false)->select('id', 'display_name', 'server_ip_address', 'server_password', 'status_type_id', 'account_type_id')->get()->toArray();
$index = 0;
$accounts = [];
foreach($results as $result)
{
$accountType = AccountType::where('id', $result['account_type_id'])->select('name')->get()->toArray();
$statusType = StatusType::where('id', $result['status_type_id'])->select('name')->get()->toArray();
$accounts[$index]['account_type'] = (isset($accountType[0]) && isset($accountType[0]['name'])?$accountType[0]['name']:"Unknown";
$accounts[$index]['status_type'] = (isset($statusType[0]) && isset($statusType[0]['name'])?$statusType[0]['name']:"Unknown";
$index++;
}
return $accounts;
}
The problem is your "debug" code only checked if it was working for the 1st iteration of the loop, it may still have not been working for the Nth element.
However if this does fix your problem the next question is why are there accounts associated with invalid account type ids. This may be a symptom of a larger problem.

Filtering a Multidimensional Array based of another array

I'm creating a PHP class that manipulates csv files.
As part of the class I have a function that allows the data to be filtered showOnlyWhere. However I get this error Invalid argument supplied for foreach() on line 331 (the line with the foreach statement). I tried adding global $arr; but that didn't work. How would i fix it?
$this -> rows is a multi-dimensional array that contains all the csv data.
$arr is in the format:
$key=>$val array(
$key = Column Name
$val = value that column should contain
)
Below is the showOnlyWhere function
function showOnlyWhere($arr)
{
if($this->showOnlyWhere == true){
$rows = $this->filteredRows;
}
else{
$rows = $this->rows;
}
$filter = function ($item){
global $arr; // didn't work
foreach($arr as $chkCol => $chkVal){
if ($item[$arr[$chkCol]] != $chkVal ){
return false;
break(3);
}
}
return true;
};
$this->filteredRows = array_filter($rows,$filter);
$this->showOnlyWhere = true;
}
I think the error might have something to do with the Anonymous function - but I'm not really sure.
instead of using global $arr you can make $arr available to the anonymous function via use
$filter = function ($item) use ($arr) {
//global $arr; // didn't work
foreach($arr as $chkCol => $chkVal){
if ($item[$arr[$chkCol]] != $chkVal ){
return false;
}
}
return true;
};
Also, I noticed that you are assigning $rows = $this->filteredRows; before you populate $this->filteredRows. I'm not sure if that's intentional?
Format for your $arr is wrong.
this is wrong:
$key=>$val array(
$key = Column Name
$val = value that column should contain
)
You cannot supply class objects to foreach, it should be a valid array.
It should be like this:
$arr=array(
$key => 'Column Name',
$val = 'value that column should contain'
);
So first convert your object to a valid array.

How to generate a longer isset() statement in PHP?

I have an interesting question today. Lets say I have an array of form fields:
array('field1', 'field2', 'field3');
I would basically want to generate an if statement which check if all of the provided fields are exists or not.
So something like this:
function ($array){
$stm = '';
foreach($array as $key){
$stm .= 'isset($_POST['.$key.']) && ';
}
if (rtrim($stm, ' && ')){
echo 'Fields are exists.';
}
}
The problem with the above function is that it takes the created statement as a String and not a variable, so it always exsits. Is there any way that I can generate something like this, which would work?
You're thinking about this the wrong way. If I understood correctly, you have an array of values, that are also POST keys, and you want to check if all of them are set. In this case I'd do something like:
function isset_multiple($array){
foreach($array as $post_key){
if(!isset($_POST[$post_key])) // if one of them is not set, return false
return false;
}
return true; // none of the foreach loops returned false, so all must be set
}
What you can do is check if array keys are set by using variable names, for example
$keyName = "field1";
if ( isset($_POST[$keyName]) === true ) { /* ... */ }
The example above can be implemented in a foreach loop.
Just execute the isset and count:
function ($array){
$count = 0;
foreach($array as $key){
if (isset($_POST[$key]) $count++;
else // you can already exit here...
}
if (count($array) === $count){
echo 'All fields exist.';
}
}
Try this..
function arrayHasKeys(array $array, array $keys)
{
return !((bool) array_diff_key($array, $keys));
}
var_dump(arrayHasKeys($_POST, array('field1', 'field2', 'field3')));
Its quite simple and reusable. Its not a good practice to use global vars inside a function.

How to pass an array into a function, and return the results with an array

So I'm trying to learn how to pass arrays through a function, so that I can get around PHP's inability to return multiple values. Haven't been able to get anything to work so far, but here is my best try. Can anybody point out where I'm going wrong?
function foo($array)
{
$array[3]=$array[0]+$array[1]+$array[2];
return $array;
}
$waffles[0]=1;
$waffles[1]=2;
$waffles[2]=3;
foo($waffles);
echo $waffles[3];
For clarification: I want to be able to pass multiple variables into a function, do something, then return multiple variables back out while keeping them seperate. This was just an example I was trying to get working as a work around for not being able to return multiple variables from an array
You seem to be looking for pass-by-reference, to do that make your function look this way (note the ampersand):
function foo(&$array)
{
$array[3]=$array[0]+$array[1]+$array[2];
}
Alternately, you can assign the return value of the function to a variable:
function foo($array)
{
$array[3]=$array[0]+$array[1]+$array[2];
return $array;
}
$waffles = foo($waffles)
You're passing the array into the function by copy. Only objects are passed by reference in PHP, and an array is not an object. Here's what you do (note the &)
function foo(&$arr) { # note the &
$arr[3] = $arr[0]+$arr[1]+$arr[2];
}
$waffles = array(1,2,3);
foo($waffles);
echo $waffles[3]; # prints 6
That aside, I'm not sure why you would do that particular operation like that. Why not just return the sum instead of assigning it to a new array element?
function foo(Array $array)
{
return $array;
}
Try
$waffles = foo($waffles);
Or pass the array by reference, like suggested in the other answers.
In addition, you can add new elements to an array without writing the index, e.g.
$waffles = array(1,2,3); // filling on initialization
or
$waffles = array();
$waffles[] = 1;
$waffles[] = 2;
$waffles[] = 3;
On a sidenote, if you want to sum all values in an array, use array_sum()
I always return multiple values by using a combination of list() and array()s:
function DecideStuffToReturn() {
$IsValid = true;
$AnswerToLife = 42;
// Build the return array.
return array($IsValid, $AnswerToLife);
}
// Part out the return array in to multiple variables.
list($IsValid, $AnswerToLife) = DecideStuffToReturn();
You can name them whatever you like. I chose to keep the function variables and the return variables the same for consistency but you can call them whatever you like.
See list() for more information.
i know a Class is a bit the overkill
class Foo
{
private $sum = NULL;
public function __construct($array)
{
$this->sum[] = $array;
return $this;
}
public function getSum()
{
$sum = $this->sum;
for($i=0;$i<count($sum);$i++)
{
// get the last array index
$res[$i] = $sum[$i] + $sum[count($sum)-$i];
}
return $res;
}
}
$fo = new Foo($myarray)->getSum();
Here is how I do it. This way I can actually get a function to simulate returning multiple values;
function foo($array)
{
foreach($array as $_key => $_value)
{
$str .= "{$_key}=".$_value.'&';
}
return $str = substr($str, 0, -1);
}
/* Set the variables to pass to function, in an Array */
$waffles['variable1'] = "value1";
$waffles['variable2'] = "value2";
$waffles['variable3'] = "value3";
/* Call Function */
parse_str( foo( $waffles ));
/* Function returns multiple variable/value pairs */
echo $variable1 ."<br>";
echo $variable2 ."<br>";
echo $variable3 ."<br>";
Especially usefull if you want, for example all fields in a database
to be returned as variables, named the same as the database table fields.
See 'db_fields( )' function below.
For example, if you have a query
select login, password, email from members_table where id = $id
Function returns multiple variables:
$login, $password and $email
Here is the function:
function db_fields($field, $filter, $filter_by, $table = 'members_table') {
/*
This function will return as variable names, all fields that you request,
and the field values assigned to the variables as variable values.
$filter_by = TABLE FIELD TO FILTER RESULTS BY
$filter = VALUE TO FILTER BY
$table = TABLE TO RUN QUERY AGAINST
Returns single string value or ARRAY, based on whether user requests single
field or multiple fields.
We return all fields as variable names. If multiple rows
are returned, check is_array($return_field); If > 0, it contains multiple rows.
In that case, simply run parse_str($return_value) for each Array Item.
*/
$field = ($field == "*") ? "*,*" : $field;
$fields = explode(",",$field);
$assoc_array = ( count($fields) > 0 ) ? 1 : 0;
if (!$assoc_array) {
$result = mysql_fetch_assoc(mysql_query("select $field from $table where $filter_by = '$filter'"));
return ${$field} = $result[$field];
}
else
{
$query = mysql_query("select $field from $table where $filter_by = '$filter'");
while ($row = mysql_fetch_assoc($query)) {
foreach($row as $_key => $_value) {
$str .= "{$_key}=".$_value.'&';
}
return $str = substr($str, 0, -1);
}
}
}
Below is a sample call to function. So, If we need to get User Data for say $user_id = 12345, from the members table with fields ID, LOGIN, PASSWORD, EMAIL:
$filter = $user_id;
$filter_by = "ID";
$table_name = "members_table"
parse_str(db_fields('LOGIN, PASSWORD, EMAIL', $filter, $filter_by, $table_name));
/* This will return the following variables: */
echo $LOGIN ."<br>";
echo $PASSWORD ."<br>";
echo $EMAIL ."<br>";
We could also call like this:
parse_str(db_fields('*', $filter, $filter_by, $table_name));
The above call would return all fields as variable names.
You are not able to return 'multiple values' in PHP. You can return a single value, which might be an array.
function foo($test1, $test2, $test3)
{
return array($test1, $test2, $test3);
}
$test1 = "1";
$test2 = "2";
$test3 = "3";
$arr = foo($test1, $test2, $test3);
$test1 = $arr[0];
$test2 = $arr[1];
$test3 = $arr[2];
Another way is:
$NAME = "John";
$EMAIL = "John#gmail.com";
$USERNAME = "John123";
$PASSWORD = "1234";
$array = Array ("$NAME","$EMAIL","$USERNAME","$PASSWORD");
function getAndReturn (Array $array){
return $array;
}
print_r(getAndReturn($array));

Categories