I have this idea of an multiarray with my files sorted into different groups/arrays.
Thinking it would be the easiest and most clean way to check what file we're inside, and should the navigation state be set to active on navigation tab 1,2 or 3?
I have this array;
Array
(
[home] => Array
(
[0] => index.php
[1] => something.php
)
[tour] => Array
(
[0] => tour.php
)
[tutorials] => Array
(
[0] => tutorials.php
)
)
The idea is, if i click on the home navigation button it goes to the index.php and a function checks whether it's the Home button that needs the active state, or the Tour button. In this case its the Home button.
[home] => Array
(
[0] => index.php
I made this function
function findNavigationActive($tap, $filename) {
if(in_array($filename, $topNavigationPages[$tap])) {
return 1;
}
return 0;
}
it should check, if index.php ($filename) is in the Home ($tap) array or navi-tap, then return 1. Unfortunately i get this error insted;
Warning: in_array() expects parameter 2 to be array, null given in /project/../../topNavigationHandler.php on line 21
What am I doing wrong?
FIXED
Used global $topNavigationPages; outside the function, and set $topNavigationPages values (array) beneath, and again used global $topNavigationPages inside the function to pull the array inside.
Thanks #tombs !
What this error means is that the second parameter isn't an array, therefore you can try something like this.:
if (is_array($topNavigationPages[$tap])) {
if(in_array($filename, $topNavigationPages[$tap])) {
return 1;
}
}
return 0;
You can do this without nesting the if loops by using a strict and operator.
Hope this helps
Note:
To resolve your scope issue you can use either a global value or a constant. To use a constant use the 'define' function, for a global declare the variable as such at the beginning of your file and in every subsequent function that you use it in. I strongly recommend using a constant.
Related
Here is my code:
\app\Controllers\My_controller.php
namespace App\Controllers;
use CodeIgniter\Events\Events;
class My_controller extends App_Controller {
function __construct() {
parent::__construct();
require_once(APPPATH . "update_value.php");
}
function index() {
$array = array("foo", "bar");
Events::trigger('add_value_to_array', $array);
print_r($array);
}
}
\app\update_value.php
use CodeIgniter\Events\Events;
Events::on('add_value_to_array', function($array) {
error_log("add_value_to_array" . PHP_EOL, 3, "events.txt");
array_push($array, "new");
return $array;
});
I'm getting this output:
Array ( [0] => foo [1] => bar )
But it's triggering the event because it's giving a log containing this text: add_value_to_array
I want the updated array containing the 'new' item. My expected result:
Array ( [0] => foo [1] => bar [2] => new )
Is it possible? Thanks in advance.
Passing by reference vs. passing by value
When you pass a parameter to a function and subsequently make changes to that parameter within the function, the PHP interpreter passes that parameter by copy, not by reference. This means that changes you make to the parameter inside the function have no effect on the original value outside of the function.
Hence why you don't see the value of $array updated outside of the Event callback. The array you're expecting to see is returned by that Event callback, but you're not capturing it.
If you need to modify $array in-place, you tell PHP to pass by reference by prefixing the parameter with an ampersand (&$array) when passing it.
function values($id,$col)
{
$vals = [1=>['name'=>'Lifting Heavy Boxes']];
return $vals[$id][$col];
}
$complete = [1=>["id"=>"2","sid"=>"35","material_completed"=>"1","date"=>"2017-12-18"]];
$form = 'my_form';
array_walk($complete, function(&$d,$k) use($form) {
$k = values($k, 'name').' ['.date('m/d/y',strtotime($d['date'])).'] ('.$form.')';
echo 'in walk '.$k."\n";
});
print_r($complete);
the echo outputs:
in walk Lifting Heavy Boxes [12/18/17] (my_form)
the print_r outputs:
Array
(
[1] => Array
(
[id] => 2
[sid] => 35
[material_completed] => 1
[date] => 2017-12-18
)
)
I have another array walk that is very similar that is doing just fine. The only difference I can perceive between them is in the one that's working, the value $d is already a string before it goes through the walk, whereas in the one that's not working, $d is an array that is converted to a string inside the walk (successfully, but ultimately unsuccessfully).
Something I'm missing?
And here's the fixed version:
array_walk($complete, function(&$d,$k) use($form) {
$d = values($k, 'name').' ['.date('m/d/y',strtotime($d['date'])).'] ('.$form.')';
});
That's what I was trying to do anyway. I wasn't trying to change the key. I was under the mistaken impression that to change the value you had to set the key to the new value.
You cannot change the key of the array inside the callback of array_walk():
Only the values of the array may potentially be changed; its structure cannot be altered, i.e., the programmer cannot add, unset or reorder elements. If the callback does not respect this requirement, the behavior of this function is undefined, and unpredictable.
This is also mentioned in the first comment:
It's worth nothing that array_walk can not be used to change keys in the array.
The function may be defined as (&$value, $key) but not (&$value, &$key).
Even though PHP does not complain/warn, it does not modify the key.
I am trying to make a simple class that I can use to check if a value exists within an array. There is a session that contains multiple tool values. I am trying to pass the toolID to this function as well as a key and see if that value exists.
Session Data:
Array
(
[keyring] => Array
(
[tool] => Array
(
[toolID] => 1859
[keys] => Array
(
[0] => 49
[1] => 96
)
)
)
)
class Keyring
{
public function checkKey($key, $toolID){
$keyring = $_SESSION['keyring'];
if(isset($keyring)){
foreach($keyring['tool'] as $k => $v) {
if($k == 'toolID' && $v == $toolID){
if (in_array($key, $k->keys)){
return true;
}
}
}
}
return false;
}
}
$keyring = new Keyring();
print_r($keyring->checkKey(49, 1859));
In this example, I am trying to see if key 49 exists in the session for tool 1859.
I am getting the following error : Warning: in_array() expects parameter 2 to be array, null given in.
Is there a better approach for this? All I am looking for is a true/false as to whether that key exists in the keys array for the specified tool.
For my code to work for you may need to change your array a bit or change the code a bit, but rather then looping through a bunch of keys trying to find the right one we are just looking for the keys in the array if they are not set, then return false, or if we find keyring - tools - $tool_id - key_{$key_id} we are just going to return that value, if key_49 = false the function returns false. This should be a tad bit quicker to run on the server for you.
function has_keyring($tool_id, $key_id)
{
//Just to keep the code tidy let's store the tools key in $tool variable
$tool = $_SESSION['keyring']['tools'];
if(isset($tool[$tool_id]) && isset($tool[$tool_id]["key_{$key_id}"]))
return $tool[$tool_id]["key_{$key_id}"];
return false;
}
$q = $_POST['q'];
$inCart = isset($_COOKIE['cart']) ? unserialize($_COOKIE['cart']) : array();
function alreadyInCart() {
global $inCart, $good, $q;
foreach ($inCart as $inCart1) {
if ($inCart1[0] == $good->id) { // if this good already in cart
$inCart1[1] = $inCart1[1] + $q; // write sum of q's to existing array
return true; // and return true
}
}
return false; // return false if not
}
if (alreadyInCart() == false) { // if good added to cart for the first time
$inCart[] = array($good->id, $q); // add array at the end of array
}
Hello. So my problem is that I'm running a function to find out if $good->id is already inside of 2d $inCart array.
$inCart looks something like this:
Array
(
[0] => Array
(
[0] => 6
[1] => 1
)
[1] => Array
(
[0] => 5
[1] => 1
)
)
Where [0] is a good ID and [1] is an amount of this good in a cart.
So I tracked that function actually does what I want and returns true/false as expected, but looks like it only does it inside of itself. Cause if I put print_r($inCart1[1]) inside of a function it does add up and outputs the sum, as expected. But when I output the array at the end of the code (outside the function) the amount doesn't add up, just stays how it was before the function run.
Any ideas why that happens?
Ok, in case someone faces the same problem: found a solution.
Or should I say found a mistake?
The problem was with the foreach ($inCart as $inCart1). Must be replaced with foreach ($inCart as &$inCart1) in order to change array values in a loop. The other way, it just reads values, bit can't change them.
I am creating a notification class which uses the session to store messages. I need to create them as a multidimensional array, so I can take advantage of different 'namespaces', so as to keep messages from displaying on the wrong pages.
Here is an example:
print_r($_SESSION)
Array
(
[EVENT_CMS] => Array
(
[Notifier] => Array
(
[0] => 'Your settings have been saved.'
[1] => 'You must re-upload...'
)
)
)
Now on the settings page, these messages will print with a call to the proper method.
I am having trouble setting up the message container within the class. This is what my constructor looks like:
public function __construct($namespace = 'Notifier') {
$this->_session_start();
if(defined('SESSION_NAMESPACE')){
$this->notifications =& $_SESSION[SESSION_NAMESPACE][$namespace];
} else {
$this->notifications =& $_SESSION[$namespace];
}
}
(The SESSION_NAMESPACE constant is defined, so the true block is executed.)
$Notify = new Notifier();
$Notify->add($_GET['test']);
print_r($_SESSION);
The above code yields me this array:
$_SESSION
Array
(
[EVENT_CMS] => Array
(
[Notifier] => 1
)
)
The add message method should update the session, right? Since the notifications array is a reference? The call to update_session() has no effect on the output...
public function add($message, $class = NULL) {
$message_node = $message;
$this->notifications[] = $message_node;
$this->update_session();
}
public function update_session(){
$this->SESSION[$this->namespace] &= $this->notifications;
}
You are mixing up the bitwise operator with the reference operator. The wrong one is used in your update_session() method.