I am getting results from a mysql table and putting each cell into an array as follows:
$sqlArray = mysql_query("SELECT id,firstName FROM members WHERE id='$id'");
while ($arrayRow = mysql_fetch_array($sqlArray)) {
$friendArray[] = array(
'id' => $arrayRow['id'],
'firstName' => $arrayRow['firstName'],
);
}
Then I do a search for a specific friend. For example if I want to search for a friend name Osman, i would type and o and it will return to me all the results that start with the letter o. Here is my code for that:
function array_multi_search($array, $index, $pattern, $invert = FALSE) {
$output = array();
if (is_array($array)) {
foreach($array as $i => $arr) {
// The index must exist and match the pattern
if (isset($arr[$index]) && (bool) $invert !== (bool) preg_match($pattern, $arr[$index])) {
$output[$i] = $arr;
}
}
}
return $output;
}
$filtered = array_multi_search($friendArray, 'firstName', '/^o/i');
and then it will print out all the results. My problem is that it returned an error saying "Invalid argument supplied to foreach()" and that is why I added the if(is_array)) condition. It is working fine if I leave this code in the index.php page, but I moved it to a subfolder named phpScripts and it doesn't work there. Any Help?
$output is not returning any value because apparently $friendArray is not an array. But I verified that it is by using print_r($friendArray) and it returns all the member's id and firstName.
P.S. I use JavaScript to the the call using AJAX.
If your array structure is such:
$friendArray[] = array(
'id' => $arrayRow['id'],
'firstName' => $arrayRow['firstName'],
);
This means your array is indexed and two levels.
So the correct way to walk through it is:
foreach($array as $cur_element) {
$id = $cur_element['id'];
$firstName = $cur_element['firstName'];
}
Change this:
foreach($array as $i => $arr) {
To this:
foreach((array)$array as $i => $arr) {
Are you sure that $array is not empty?
Related
I have two function to add remove parameters to the query string. The "add_query_params" (thanks to this forum) is working nicely and I can now add multiple tags to the query string of the same type.
For example
http://example.com?tags[]=flowers&tags[]=shrubs&category[]=garden
As you can see, I can add multiple of the same parameters, I am also querying these nicely using queryfilters.
However my newest problem, is simply removing a single tag type without affecting the rest of the query string. I will then rebuild the query without the deleted tag.
Someone kindly yesterday helped me to to a point but this removes ALL tag key values, not just the specified tag.
So if I was to delete say $tags[]shrubs from the above URL it would actually delete BOTH tag[]shrubs AND $tags[]flowers.
This obviously isn't very intuitive for a filter system I am devising. What I would like to know is how to remove just the single key value pair and leave the other keys pairs intact.
Here is my helper function
//Accept a param array which passthrough through tag type eg category/tag and value
function remove_query_params(array $params = [])
{
//Set to array
$existingParams = [];
$existingParams = request()->query();
foreach($params as $key=>$value){
if (isset($existingParams[$value])) {
unset($existingParams[$value]);
}
}
$query = http_build_query($existingParams);
return url()->current() . '?' . $query;
}
//Need to return: user removes tag from filter in blade, URL recontructs without the passed through tag value
//Before
//http://example.com?tags[]=flowers&tags[]=shrubs&category[]=garden
//After
//http://example.com?tags[]=flowers&category[]=garden
This does not work, if I change $value to $key then it will will, but it will remove all keys of the same type, not the behaviour I would like.
I activate this behaviour via a call in the blade template, this forms a href
//Pass through parameter type and parameter value
{{remove_query_params(['category' => $category->id]) }}
Has anybody got any pointers as to where I go next?#
Thanks and fingers crossed I am not far off :)
Adam
I hope this solution will help you:
<?php
function remove_query_params(array $params = [])
{
//Set to array
$existingParams = [
'tags' => [
'aaaa',
'bbbb'
],
'category' => 'ccc'
];
// go trough all parameters
foreach ($existingParams as $key1 => $value1) {
// go to the parameters, which need to be deleted
foreach ($params as $key2 => $value2) {
// only if the keys equals, do something
if ($key1 === $key2) {
// if the param is an array
if (is_array($value1)) {
foreach ($value1 as $k => $v) {
// if the elements to delete are an array
if (is_array($value2)) {
foreach ($value2 as $b => $r) {
if ($v == $r) {
unset($existingParams[$key1][$k]);
}
}
} else {
if ($v == $value2) {
unset($existingParams[$key1][$k]);
}
}
}
} else {
if (isset($existingParams[$key2])) {
unset($existingParams[$key2]);
}
}
}
}
}
$query = http_build_query($existingParams);
return $query;
}
echo remove_query_params(['tags' => 'aaaa']);
echo "\n";
echo remove_query_params(['tags' => ['aaaa', 'bbbb']]);
echo "\n";
echo remove_query_params(['category' => 'ccc']);
echo "\n";
tags is not an associated array. It is just a list of strings. Also, look at the value of $existingParams = request()->query(); It is not the tags array. It is an object that contains it. That is why when you use $key it works but deletes everything because $key is tags. So, in your check $existingParams['tags'] should be checked for the shrubs value. in_array is what you are looking in this case.
Hope this will solve your problem.I just provided the core function to get the things done in a way
$query = "tags[]=flowers&tags[]=shrubs&category[]=garden";
echo (remove_query_params( [ 'tags' => 'shrubs' ], $query ));
function remove_query_params(array $params = [], $query )
{
parse_str( $query, $existingParams );
$existing_keys = array_keys( $existingParams);
foreach($params as $key=>$value){
if( in_array( $key, $existing_keys ) ){
foreach ($existingParams[$key] as $param_key => $param_value) {
if( $param_value == $value ){
unset( $existingParams[$key][$param_key] );
}
}
}
}
$query = http_build_query($existingParams);
return $query;
}
Please, help with multidimensional array push. Please, see the code and comments below. The push is giving an error. The assigning is giving the last row only.
if (!isset($_SESSION['page_qstn_answer'])) {
$_SESSION['page_qstn_answer'] = array("page" => array(), "qstn" => array(), "answer" => array()
}
if (!isset($temp)) {
$temp = array("page" => array(), "qstn" => array(), "answer" => array() );
}
while($question = mysqli_fetch_assoc($question_set) ) {
if(isset($question['position']) ){
$post_qstn = $question['position'];
If(isset($_POST[$qstn]) ) {
//printing all rows from db correctly as below
//echo "Question ".$qstn." - selected answer ".$answer . " on page ".$page ."<br />";
if (isset($temp) ){
$temp = array ("page"=>$page, "qstn"=>$qstn,"answer"=> $answer);}
//show a one by one array rows correctly but $temp has a one row at a time that is Ok
//print_r($temp);
// Try to accumulate $temp into $_Session array. Push is giving an error
//$_SESSION['pages_qstn_answers'] = array_push($_SESSION['pages_qstn_answers'], $temp);
// No error but no accumulation as foreach as below shows the only one last row.
$_SESSION['pages_qstn_answers'] = $temp;
}
foreach ($_SESSION['pages_qstn_answers'] as $key => $value) {
echo "$key = $value\n";}
I used a function that I found on the website to delete all previously added the same questions before accumulating the $temp entries into the final array as there should be the only one question with a one answer. It seems a working. If somebody could see some shortcomings there please advise. Thanks
remove_elm($_SESSION['pages_qstn_answers'], "qstn", $qstn, TRUE);
$_SESSION['pages_qstn_answers'][] = $temp;
function remove_elm($arr, $key, $val, $within = FALSE) {
foreach ($arr as $i => $array)
if ($within && stripos($array[$key], $val) !== FALSE && (gettype($val) === gettype($array[$key])))
unset($arr[$i]);
elseif ($array[$key] === $val)
unset($arr[$i]);
return array_values($arr);
}
You have a misunderstanding of how array_push() works. It does not return the array, it just appends whatever value you have to it. So when you do:
$_SESSION['pages_qstn_answers'] = array_push($_SESSION['pages_qstn_answers'], $temp);
The right hand side of the equation simply returns an integer containing the number of elements in the new array. So say you now have 5 elements in your array, you are essentially doing
$_SESSION['pages_qstn_answers'] = 5;
Instead just do:
array_push($_SESSION['pages_qstn_answers'], $temp);
or since you're only appending one value I would stick with:
$_SESSION['pages_qstn_answers'][] = $temp;
I got an array like this:
$array[0][name] = "Axel";
$array[0][car] = "Pratzner";
$array[0][color] = "black";
$array[1][name] = "John";
$array[1][car] = "BMW";
$array[1][color] = "black";
$array[2][name] = "Peggy";
$array[2][car] = "VW";
$array[2][color] = "white";
I would like to do something like "get all names WHERE car = bmw AND color = white"
Could anyone give advice on how the PHP spell would look like?
function getWhiteBMWs($array) {
$result = array();
foreach ($array as $entry) {
if ($entry['car'] == 'bmw' && $entry['color'] == 'white')
$result[] = $entry;
}
return $result;
}
Edited: This is a more general solution:
// Filter an array using the given filter array
function multiFilter($array, $filters) {
$result = $array;
// Removes entries that don't pass the filter
$fn = function($entry, $index, $filter) {
$key = $filter['key'];
$value = $filter['value'];
$result = &$filter['array'];
if ($entry[$key] != $value)
unset($result[$index]);
};
foreach ($filters as $key => $value) {
// Pack the filter data to be passed into array_walk
$filter = array('key' => $key, 'value' => $value, 'array' => &$result);
// For every entry, run the function $fn and pass in the filter data
array_walk($result, $fn, $filter);
}
return array_values($result);
}
// Build a filter array - an entry passes this filter if every
// key in this array corresponds to the same value in the entry.
$filter = array('car' => 'BMW', 'color' => 'white');
// multiFilter searches $array, returning a result array that contains
// only the entries that pass the filter. In this case, only entries
// where $entry['car'] = 'BMW' AND $entry['color'] = 'white' will be
// returned.
$whiteBMWs = multiFilter($array, $filter);
Doing this in code is more or less emulating what a RDBMS is perfect for. Something like this would work:
function getNamesByCarAndColor($array,$color,$car) {
$matches = array();
foreach ($array as $entry) {
if($entry["color"]== $color && $entry["car"]==$car)
matches[] = $entry["name"];
}
return $matches;
}
This code would work well for smaller arrays, but as they got larger and larger it would be obvious that this isn't a great solution and an indexed solution would be much cleaner.
I am trying to make first array value to uppercase.
Code:
$data = $this->positions_model->array_from_post(array('position', 'label'));
$this->positions_model->save($data, $id);
So before save($data, $id) to database I want to convert position value to uppercase. I have tried by this
$data['position'] = strtoupper($data['position']);
but than it is not storing the value in db with uppercase but as it is what user inputs.
Current output of $data:
Array ( [position] => it [label] => Information Technology )
And I want it in uppercase as IT
Added Model Method
public function get_positions_array($id = NULL, $single = FALSE)
{
$this->db->get($this->_table_name);
$positions = parent::get($id, $single);
$array = array();
foreach($positions as $pos){
$array[] = get_object_vars($pos);
}
return $array;
}
Main MY_Model method
public function array_from_post($fields)
{
$data = array();
foreach ($fields as $field) {
$data[$field] = $this->input->post($field);
}
return $data;
}
This should work:
$data = $this->positions_model->array_from_post(array('position', 'label'));
$data['position'] = strtoupper($data['position']);
$this->positions_model->save($data, $id);
If Its not, then $data array have only read attribute.
The array_from_post() method returns an array with the format below:
$data = array(
'position' => 'it',
'label' => 'Information Technology'
);
So, you could make first value of the array to uppercase, by using array_map or array_walk functions as follows:
$data = array_map(function($a) {
static $i = 0;
if ($i === 0) { $i++; return strtoupper($a); }
else return $a;
}, $array);
Note: This only works on PHP 5.3+, for previous versions, use the function name instead.
Here is the array_walk example, which modifies the $data:
array_walk($data, function(&$value, $key) {
static $i = 0;
if ($i == 0) { $i++; $value = strtoupper($value); }
});
Again, if you're using PHP 5.2.x or lower, you could pass the function name instead.
I have an array with structure generated like this:
$groups = array();
while ($group = mysql_fetch_array($groups_result)) {
$groups[] = array( 'id' => $group['id'], 'name' => $group['name']);
}
How can I later in the code get the name of the group by its id? For example, I would like a function like:
function get_name_by_id($id, $array);
But I'm looking for some solution which is already implemented in PHP. I know it would be easier to make arrays with array[5] = array('name' => "foo") etc where 5 in this case is id, but in my code there is a lot of arrays already created like i mentioned above and I cannot easily switch it.
$groups = array();
while ($group = mysql_fetch_assoc($groups_result)) {
$groups[$group['id']] = array( 'name' => $group['name']);
}
$name = $groups['beer']['name'];
also please not using fetch_assoc is more efficient than fetch array
function get_name_by_id($id, $data) {
foreach($data as $d) {
if ($d['id'] == $id) {
return $d['name'];
}
}
// return something else, id was not found
}