in_array is not finding values that are in the array - php

I'm getting strange results when trying to check a $_GET variable against a whitelist array. The variable is in the array but in_array is not finding it. I'll descibe what's happening as best I can.
The $_GET vars are set from option/select choices, three altogether. Only one of the options is giving me a problem. To run a SELECT query, there have to be at least two options chosen. Any combination of the other two options works as expected.
To get the option/select lists I have a SELECT query retrieving a record subset.
From that recordset I use a foreach loop to get the various values to populate the select tags. So the select values are populated by values from the db table. The whitelist arrays are copied from the db.
I check any $_GET vars against the whitelist arrays. The option in question can be a comma-delimited string (eg. 'Italian,Pizza' or 'American, Barbeque, Sandwiches').
To get the select value list for this option I use implode to create a comma-delimited list of each category, then use explode to create an array, then use array_unique to get an array with single instances of each category. When echoing this array everything is right (it populates the select choices correctly).
implode outputs:
Italian,Pizza,Italian,Pizza,Italian,Pizza,Italian,Italian,Sandwiches,Italian,Pizza,Italian
explode outputs:
Array
(
[0] => Italian
[1] => Pizza
[2] => Italian
[3] => Pizza
[4] => Italian
[5] => Pizza
[6] => Italian
[7] => Italian
[8] => Sandwiches
[9] => Italian
[10] => Pizza
[11] => Italian
)
array_unique outputs:
Array
(
[0] => Italian
[1] => Pizza
[8] => Sandwiches
)
So, the URL can be like:
../search.php?var_src=Sandwiches&city_src=Cityname
To sanitize the $_GET vars:
if((isset($_GET['var_src'])) && in_array($_GET['var_src'], $var_array)) {
$var_sort = $_GET['var_src'];
}
Again, $var_array is an array copied from the db table.
This is where the code stops because the $_GET var is not being found in the array.
If I change one of the db records to just one category value (eg. 'Sandwiches') and select that option in the list, then the results are as expected. However, if the record has more than one category value (each of which is in the whitelist array) like 'Pizza,Sandwiches', then neither of them work.
The kicker is that if I include the category value 'Italian', whether alone or with other values in the db record, and select for this value, then it works. I have no idea why.
So the code works if that particular value ('Italian') is selected whether or not others are included as a comma-delimited string for the record, and does not work with other values where there are more than one associated with the record.
I confirmed that the offending value is in the URL and so should work with the code above (in_array($_GET['var_src'], $var_array)).
Also, I don't know why changing the db record would have an effect because the sanitizing against the whitelist happens before selecting records based on the passed values. As far as I can tell, in_array is just not finding legitimate values in the array.
Hope I haven't made this confusing. Thanks for any help.

Not sure if this will help you, try to change it like in this example:
$opt = array( 'Italian,Pizza' , 'American, Barbeque, Sandwiches');
$opts = implode(',',$opt);
$opta = explode(',',$opts);
foreach ($opta as $key=>$value) {
$opta[$key]=trim($value);
}
$opta = array_flip($opta);
var_export($opta);
//now test it simply with isset:
$val = trim($_GET['var_src']);
echo isset($opta[$val])? 'yes':'no';

Related

Using values in an PHP array

I have an array split in half, but now i want to use the values in the array.
The array is split like this
$teams = array_chunk($lista, count($lista)/2);
Output
Array ( [0] => Array ( [0] => 4 [1] => 3 ) [1] => Array ( [0] => 4 [1] => 4 ) )
the numbers represent user id's.
How can i use these numbers?
Let's say that i want to select all id's in the first array (The idea is for these two arrays to act like teams) and then assign these values to a team column in my database.
Let me explain a bit more
I want the id's in the array to be assigned to a team.
In array one the team will be, uhm. Blue! and in the other array the team will be red.
I will be using these randomised arrays to update my database table which contains a column called "team".
Basically my question is how i can use these arrays to assign the specific id's in each array to a team. example, Can i select everything in array one and update all those values to team blue?
For this question i'm sorry because i really don't know what i should include to make this question answerable, it might already be! but i'm not sure, so i if i have missed something just comment and i will clarify.
Update
This is what my database table looks like
https://gyazo.com/ed3c681575b26f31b77246436b43439a
As you can see, i have a column called "team", i want to update this to something depending on what team the user got selected into using the array splitter.
Everyone in Array one will have this updated to "team blue", and team red for array2.
You could use a For Loop to construct a query that does this for you.
An array inside of an array is called a Multidimensional Array.
You can access the elements of an array inside an array by just simply indexing twice:
$array = [ [1,2], [3,4] ];
echo $array[0][0]; // echo's 1
So you could loop over the first array for each team and loop into the second array to get each user id:
$array = [ [1,2], [3,4] ];
foreach($array as $team_id => $player_ids){
foreach($player_ids as $player_id){
echo "Player $player_id is in team $team_id";
}
}
This example uses a Foreach Loop.
In this for loop you can construct a query that updates the rows for the players in the database.
If you are new to arrays in PHP I suggest you read this article: http://php.net/manual/en/language.types.array.php

Silverstripe 3.5 - How to query for specific columns and return an array

I'm trying to do a select all to get three columns from a single table and then simply use the result as an array. Without the expense of a loop.
I have tried this using the ORM method:
DataObject::get('City')->sort('Name ASC')->toNestedArray();
This gives me an array perfectly. But I can't see a way to only return the columns I want. It returns all columns. This is a problem because I am json encoding this array and the packet is 3 times as big as it needs to be due to this.
So I tried this using SQLQuery instead:
DB::query('SELECT "ID","Name","ParentID" FROM "City"');
Now this allows me to select the three fields, but as far as I can tell, there is no method to return this query as an array like toNestedArray()
Searched high and low but nothing fits. Any ideas?
Edit: Should have mentioned I have tried setQueriedColumns() sorry. This doesn't seem to be intended for what I am doing here.
$cities = AspireCity::get()->sort(['Name' => 'ASC'])->setQueriedColumns(['ID', 'Name']);
Debug::dump($cities->toNestedArray());
Outputs:
Array
(
[0] => Array
(
[ClassName] => City
[LastEdited] => 2017-09-26 11:14:16
[Name] => Acacia Bay
[ID] => 70
[RecordClassName] => City
[Created] =>
[ParentID] => 9
)
[1] => Array
(
[ClassName] => City
[LastEdited] => 2017-09-26 11:14:16
[Name] => Ahaura
[ID] => 71
[RecordClassName] => City
[Created] =>
[ParentID] => 9
)
According to the API Docs, setQueriedColumns() is your friend:
From your question I assume the DataObject you want to query is called City, so we need this to get all cities out of the database:
City::get();
This returns a DataList and queries the database when you need it. Up to now, your DB doesn't know anything that you want some data from it. So let's refine it, sort it by "Name" ASC. I like the array syntax much more, IMHO it's easier to read, and if you need to sort against a second row, just add it to the array:
City::get()
->sort(['Name' => 'ASC']);
Now you wanted, for some reasons, just some columns back. As I don't know what database fields your City DataObject has, I assume you just want 'Name' and 'ZIP':
City::get()
->sort(['Name' => 'ASC'])
->setQueriedColumns(['Name', 'ZIP']);
This limits the queried columns and you can add toNestedArray() to get the data out as a pure vintage array. This might be useful to pass the data to an API, but maybe it's better to leave the objects and use City specific logic in your code.
So I decided that this was a case a of over-reliance on existing SS helper methods. While toNestedArray() is very handy, my focus on it was to based primarily on thinking I can avoid a loop by using it. When in reality, the method is of course a loop. So really my concern is unfounded.
The most important goal was reducing the dataset at the time of query. So the solution simply focuses on that.
// Inject the default country/city/suburb data as vars so they can be easily filtered.
$location['countries'] = DB::query('SELECT "ID","Description" FROM "Country" ORDER BY "ID" ASC');
$location['cities'] = DB::query('SELECT "ID","Name","ParentID" FROM "City" ORDER BY "Name" ASC');
$location['suburbs'] = DB::query('SELECT "ID","Name","ParentID" FROM "Suburb" ORDER BY "Name" ASC');
$masterLocationArray = [];
foreach($location as $key => $data) {
$locationArray = [];
foreach($data as $item) {
$locationArray[] = $item;
}
$masterLocationArray[$key] = $locationArray;
}
// $masterLocationArray is our filtered, tidy array. Do stuff with it

PHP -modify value of last accessed element in multidimensional associative array

I am reading a GEDCOM-formatted family tree flat file, and producing an array from the data for staging into table. If I encounter the values CONC <some value>, then, instead of adding an element, I need to append <some value> to the value of the last element that was just inserted (regardless of dimension depth).
I tried with current(...) etc but does this work for a multidimensional associative array?
please consider following element in an array:
[#N163#] => Array ( [INDI] => Array ( [TEXT] => Some data of this person) )
if the next line reads "1 CONC including his profession"
instead of adding a line as such
[#N163#] => Array (
[INDI] => Array ( [TEXT] => Some data of this person)
[INDI] => Array ( [CONC] => including his profession) )
I would like the array to look as follows:
[#N163#] => Array (
[INDI] => Array ( [TEXT] => Some data of this person including his profession) )
What I have researched thus far:
end($theArray)
to set pointer to last inserted element followed by $theArray[key($theArray)] = .... to update this element.
But I did not get this method to work for multidimensional arrays and/or it became really messy.
And:
merging two arrays using e.g. += notation,
but this only seems to overwrite a new element, not affect the last one, if keys are same
And:
examples with foreach calls, which does not help in my case.
Hope somebody can shed some light... many thanks!
When you adding $array[#N163#][INDI][TEXT] = 'smtng'; you can save position
$pos = &$array[#N163#][INDI][TEXT];
And if you need concatenate, write
$pos .= "concate line";

Change specific array values to uppercase

I have an array with the following key/values:
FirstName, LastName, EmployeeNumber, Location
I need to convert the values contained in FirstName and LastName to all UPPERCASE.
I have tried using
array_map('strtoupper', $myARR);
But I get this error:
Warning: strtoupper() expects parameter 1 to be string, array given in
I think it is because employee number is numeric, so it errors out because a numeric is not a string? I do not know what else I can try, to attempt this. The reason being is that I have combined two arrays into one. One of the arrays coming from a DB is in all UPPER, while the other is not. This causes me to be unable to sort the array properly, as it does not see BROWN and Brown as the same value.
If I sort these five names:
BATMAN CHARLES BYRON Carl Bill
The result is this
BATMAN
BYRON
Bill
CHARLES
Carl
If I can get the ucfirst values to be all UPPER then the sort will work correctly (as one value from the table that has ucfirst only, is a 2 letter nickname (AJ) and it sorts correctly with the other data that is all UPPER).
Any ideas on how I can get the values to be UPPER for just those two portions of the array? Any help would be greatly appreciated.
EDIT
Here is some data pulled from the array:
Portion of Array with First Letter Capitalized
[59] => Array (
[0] => First
[1] => Last
[2] => 123456
[3] => Location )
Portion of Array with All Letter Capitalized
[1116] => Array (
[0] => FIRST
[1] => LAST
[2] => 123456
[3] => Location )
I cannot put the actual values here on the website, but essentially the values change for all people in the array. But at least this should show how each element in the array looks as far as uppercase values and what not.
foreach ($employees as $e) {
$e['firstName'] = strtoupper($e['firstName']);
... same for lastName
}
As an alternative to parsing all to upper case.. You could just use a case-insensitive sorting function: natcasesort
$sorted = natcasesort($myARR)
a simple way would be
$Capsfield = strtoupper($youarray['yourfeild']);
but that would not be recrusive, #Just Somebody gave a better thinking...

PHP 5.2 Function needed for GENERIC sorting of a recordset array

Somebody must have come up with a solution for this by now. We are using PHP 5.2. (Don't ask me why.) I wrote a PHP class to display a recordset as an HTML table/datagrid, and I wish to expand it so that we can sort the datagrid by whichever column the user selects. In the below example data, we may need to sort the recordset array by Name, Shirt, Assign, or Age fields. I will take care of the display part, I just need help with sorting the data array.
As usual, I query a database to get a result, iterate throught he result, and put the records into an assciateiave array. So, we end up with an array of arrays. (See below.) I need to be able to sort by any column in the dataset. However, I will not know the column names at design time, nor will I know if the colums will be string or numeric values.
I have seen a ton of solutions to this, but I have not seen a GOOD and GENERIC solution Can somebody please suggest a way that I can sort the recordset array that is GENERIC, and will work on any recordset? Again, I will not know the fields names or datatypes at design time. The array presented below is ONLY an example.
UPDATE: Yes, I would love to have the database do the sorting, but that is just not going to happen. The queries that we are running are very complex. (I am not really querying a table of Star Trek characters.) They include joins, limits, and complex WHERE clauses. Writing a function to pick apart the SQL statement to add an ORDER BY is really not an option. Besides, sometimes we already have the array that is a result of the query, rather than the ability to run a new query.
Array
(
[0] => Array
(
[name] => Kirk
[shrit] => Gold
[assign] => Bridge
)
[1] => Array
(
[name] => Spock
[shrit] => Blue
[assign] => Bridge
)
[2] => Array
(
[name] => Uhura
[shrit] => Red
[assign] => Bridge
)
[3] => Array
(
[name] => Scotty
[shrit] => Red
[assign] => Engineering
)
[4] => Array
(
[name] => McCoy
[shrit] => Blue
[assign] => Sick Bay
)
)
Well, first off, you should be sorting in the database (it's more efficient). If not
In php 5.3+:
function getSortCommand($field, $sortfunc) {
return function($var1, $var2) use ($field, $sortfunc) {
return $sortfunc($var1[$field], $var2[$field]);
}
}
in php <= 5.2, you'll need to create a pure function:
function getSortCommand($field, $sortfunc) {
return create_function('$var1, $var2', 'return '.$sortfunc.'($var1["'.$field.'"], $var2["'.$field.'"]);');
}
Usage for both:
$array = usort($array, getSortCommand('name', 'strnatcasecmp'));
To adjust the field, you just change the $field parameter. To change the sort function, just change the $sortfunc parameter...
I suggest you do it in the database. Otherwise, you can use this:
function sortby(&$arr, $column) {
usort($arr,
function ($a, $b) use ($column) {
return strcmp($a[$column], $b[$column]);
}
);
}
You should definitely do the sorting when querying the database.
You do this by adding a link like ?orderby=name&dir=asc to the <TH>s
Then when you query the database you check for the existence of $_GET['orderby']. If it exists you add an order by clause.
A clientside option is http://tablesorter.com/docs/

Categories