I'm looking for an easy solution to create a little function to merge two arrays with value concat (I'm using it to create html tag attribute):
$default["class"] = "red";
$new["class"] = "green";
$new["style"] = "display:block"
The result:
$res["class"] = "red green";
$res["style"] = "display: block";
and one more option:
if the $new is not an array, just concat with the $default["class"] (if this exist), and the other side: if the $default is a simple string, convert to array: $default["class"] = $default;
I created a function but would like to use an easier, shorter way for that:
function attrMerge( $default, $new="" ){
$res = array();
if(!is_array($default)) {
$res["class"] = $default;
}
else {
$res = $default;
}
if( $new !== "" ){
if(!is_array($new)) {
if(isset($res["class"])){
$res["class"].= " ".$new;
}
}
else {
foreach($new as $key=>$value) {
if( isset($res[$key]) ) {
$res[$key].= " ".$value;
}
else {
$res[$key] = $value;
}
}
}
}
return $res;
}
$a = attrMerge("red", array("class"=>"green", "style"=>"display: block;"));
I think this is the function that you need. I have initialised the css classes and styles as empty and in depends what you pass into the function then you get the relevant array
/**
* This function returns an array of classes and styles
*
* #param $default
* #param $new
* #return array
*/
function attrMerge($default=null, $new=nul)
{
$result = array();
$result['class'] = "";
$result['style'] = "";
// add default class if exists
if (!empty($default) && is_string($default)) {
// $default is string
$result['class'] = $default;
}
if (!empty($default)
&& is_array($default)
) {
if (array_key_exists('class', $default)
&& !empty($default['class'])
) {
// $default['class'] exists and it's not empty
$result['class'] = $default['class'];
}
if (array_key_exists('style', $default)
&& !empty($default['style'])
) {
// $default['style'] exists and it's not empty
$result['style'] = $default['style'];
}
}
// add additional classes OR styles
if (!empty($new)) {
if(!is_array($new)) {
$result['class'] = empty($result['class'])
? $new
: $result['class'] . " " . $new;
} else {
foreach ($new as $key => $value) {
if (isset($result[$key])) {
$result[$key] = empty($result[$key])
? $value
: $result[$key] . " " . $value;
} else {
$result[$key] = $value;
}
}
}
}
return $result;
}
A way I believe suits your need, hopefully it's as adaptable and effecient as you were expecting.
$array1 = array(
'class' => 'class1',
'style' => 'display: none;'
);
$array2 = array(
'class' => 'class2'
);
$arrayFinal = arrayMerge($array1, $array2);
var_dump($arrayFinal);
function arrayMerge($arr1, $arr2 = ''){
// Array of attributes to be concatenated //
$attrs = array('class');
if(is_array($arr2)){
foreach($attrs as $attr){
if(isset($arr1[$attr]) && isset($arr2[$attr])){
// Not using .= to allow for smart trim (meaning empty check etc isn't needed //
$arr1[$attr] = trim($arr1[$attr] . ' ' . $arr2[$attr]);
}
}
}else{
$arr1['class'] = trim($arr1['class'] . ' ' . $arr2);
}
return $arr1;
}
$def = ['class' => 'red'];
$new = ['class' => 'green', 'style' => 'style'];
function to_array($in) {
return is_array($in) ? $in : ['class' => $in];
}
$def = to_array($def);
$new = to_array($new);
$res = $def;
array_walk($new, function ($val, $key) use (&$res) {
$res[$key] = trim(#$res[$key] . ' ' . $val);
});
var_dump($res);
Related
$printArr = recursive($newArray); //calls recursive function
$data = [];
var_dump($data);
var_dump($printArr);
function recursive($array, $level = 0)
{
$searchingValue = 'tableName';
foreach($array as $key => $value)
{
//If $value is an array.
if(is_array($value))
{
recursive($value, $level + 1);
}
else
{
//It is not an array, so print it out.
if($key == $searchingValue)
{
echo "[".$key . "] => " . $value, '<br>';
$data[] = $value;
}
}
}
}
So I have this function and I am trying to save $value value into $data[] array. But it always returns it empty and I don't know why I can't get $value saved outside the function.
If i echo $value I get what i need but like I've mentioned the variables doesn't get saved in this case - table names.
You need to pass the $data to your recursive function. Also you need to return the $data.
Try this code :
function recursive($array, $level = 0, $data =[])
{
$searchingValue = 'tableName';
foreach($array as $key => $value)
{
//If $value is an array.
if(is_array($value))
{
recursive($value, $level + 1 , $data);
}
else
{
//It is not an array, so print it out.
if($key == $searchingValue)
{
echo "[".$key . "] => " . $value, '<br>';
$data[] = $value;
}
}
}
return $data;
}
You can't access variable $data, which is outside the function, from the function. You need to pass it by reference or return it. Small example
<?php
$a = 1;
// Your case
function b() {
$a = 4;
return true;
}
// Passing by reference
function c(&$d) {
$d = 5;
return true;
}
// Using return
function d($d) {
$d = 6;
return $d;
}
b();
var_dump($a);
c($a);
var_dump($a);
$a = d($a);
var_dump($a);
https://3v4l.org/UXFdR
I am creating my own custom cookie class and I can not seem to figure out what I am doing wrong. Here is my cookie class:
<?php
class Cookie implements CookieHandlerInterface {
private $_domain;
private $_secure;
public function __construct(array $config = array()) {
$this->_domain = isset($config['domain']) ? $config['domain'] : 'localhost';
$this->_secure = isset($config['secure']) ? $config['secure'] : false;
}
public function set($name, $value = null, $timeLength) {
if (!is_null($value)) {
if (is_array($value)) {
if ($this->__isMultiArray($array)) {
return null;
} else {
$value = $this->__arrayBuild($value);
$value = 'array(' . $value . ')';
}
} elseif (is_bool($value)) {
if ($value) {
$value = 'bool(true)';
} else {
$value = 'bool(false)';
}
} elseif (is_int($value)) {
$value = 'int(' . strval($value) . ')';
} elseif (is_float($value)) {
$value = 'float(' . strval($value) . ')';
} elseif (is_string($value)) {
$value = 'string(' . $value . ')';
} else {
return null;
}
} else {
$value = 'null(null)';
}
setcookie($name, $value, (time() + $timeLength), '/', $this->_domain, $this->_secure, true);
}
public function get($name, $defualtOutput = null) {
if (isset($_COOKIE[$name])) {
$output = rtrim($_COOKIE[$name], ')');
$xr1 = mb_substr($output, 0, 1);
if (equals($xr1, 'a')) {
$output = ltrim($output, 'array(');
return $this->__arrayBreak($output);
}
if (equals($xr1, 'b')) {
$output = ltrim($output, 'bool(');
if (equals($output, 'true')) {
return true;
} else {
return false;
}
}
if (equals($xr1, 'i')) {
$output = ltrim($output, 'int(');
return (int) $output;
}
if (equals($xr1, 'f')) {
$output = ltrim($output, 'float(');
return (float) $output;
}
if (equals($xr1, 's')) {
$output = ltrim($output, 'string(');
return $output;
}
if (equals($output, 'null(null)')) {
return null;
}
}
if (
!is_array($defualtOutput)
&& !is_bool($defualtOutput)
&& !is_int($defualtOutput)
&& !is_float($defualtOutput)
&& !is_string($defualtOutput)
&& !is_null($defualtOutput)
) {
trigger_error(
'The $defualtOutput var needs to be only certain types of var types. Allowed (array, bool, int, float, string, null).',
E_USER_ERROR
);
}
return $defualtOutput;
}
public function delete($name) {
if (isset($_COOKIE[$name])) {
setcookie($name, '', time() - 3600, '/', $this->_domain, $this->_secure, true);
}
}
private function __arrayBuild($array) {
$out = '';
foreach ($array as $index => $data) {
$out .= ($data != '') ? $index . '=' . $data . '|' : '';
}
return rtrim($out, '|');
}
private function __arrayBreak($cookieString) {
$array = explode('|', $cookieString);
foreach ($array as $i => $stuff) {
$stuff = explode('=', $stuff);
$array[$stuff[0]] = $stuff[1];
unset($array[$i]);
}
return $array;
}
private function __isMultiArray($array) {
foreach ($array as $key => $value) {
if (is_array($value)) {
return true;
}
}
return false;
}
}
?>
I set a test cookie for example app('cookie')->set('test', 'hello', 0);
sure enough it created the cookie like expected. So the cookie reads string(hello)
When I try to echo it, it echos the default value instead of the actual variable, so app('cookie')->get('test', 'test'); returns test
The get function should check if the cookie exists with isset($_COOKIE[$cookieName]) and then it should trim the extra ) with rtrim($_COOKIE[$cookieName], ')') then it should grab the first character in the string with mb_substr($_COOKIE[$cookieName], 0, 1) the 0 starts at the beginning and the 1 grabs only the first character.
After it compares it with the default (a, b, i, f, s) for example if it starts with an s its a string by default, if it was i it was sent as an int by default, etc. etc.
If they all come up as false it checks to see if it was sent as null if so it return null else it returns the default value passed.
The equals function is the same as $var1 == $var2 it is timing attack safe.
so it keeps returning the default value which is null, any help would be helpful thanks in advance.
Lol i feel real stupid i put 0 as the third argument thinking it will tell the cookie to expire when the browser session closes, but it did (time() + 0) which does not equal 0. so as it was setting the cookie it expired upon creation. So i did time() - (time() * 2). i achieved the goal i wanted.
I have a situation showed in the PHP code below, and I want to make a recursive function called check_recursive().
I have made the check_recursive() function below, but I want a recursive function, if it is possible.
Thank You!
$menu = '[{"id":"3|case_studies","children":[{"id":"2|case_studies","children":[{"id":"1|custom_links","children":[{"id":"2|faqe"}]}]}]},{"id":"11|klientet","children":[{"id":"8|klientet","children":[{"id":"7|klientet"}]}]},{"id":"9|klientet","children":[{"id":"10|klientet"}]},{"id":"4|klientet"}]';
$old_menu = json_decode($menu, true);
$new_menu = $this->check_recursive($old_menu);
function check_recursive($old_menu)
{
$i = 0;
$new_menu = [];
foreach ($old_menu as $menu_item)
{
if($name = $this->check_menu($menu_item['id']))
{
$new_menu[$i]['id'] = $menu_item['id'] . '|' . $name;
if(isset($menu_item['children']))
{
$e = 0;
foreach ($menu_item['children'] as $menu_item)
{
if($name = $this->check_menu($menu_item['id']))
{
$new_menu[$i]['children'][$e]['id'] = $menu_item['id'] . '|' . $name;
if(isset($menu_item['children']))
{
$y = 0;
foreach ($menu_item['children'] as $menu_item)
{
if($name = $this->check_menu($menu_item['id']))
{
$new_menu[$i]['children'][$e]['children'][$y]['id'] = $menu_item['id'] . '|' . $name;
if(isset($menu_item['children']))
{
$a = 0;
foreach ($menu_item['children'] as $menu_item)
{
if($name = $this->check_menu($menu_item['id']))
{
$new_menu[$i]['children'][$e]['children'][$y]['children'][$a]['id'] = $menu_item['id'] . '|' . $name;
}
$a++;
}
}
}
$y++;
}
}
}
$e++;
}
}
}
$i++;
}
return $new_menu;
}
function check_menu($string){
//Check if string exists in database
if($string){
return 'String exists';
}
return false;
}
I came up with this :
$menu = '[{"id":"3|case_studies","children":[{"id":"2|case_studies","children":[{"id":"1|custom_links","children":[{"id":"2|faqe"}]}]}]},{"id":"11|klientet","children":[{"id":"8|klientet","children":[{"id":"7|klientet"}]}]},{"id":"9|klientet","children":[{"id":"10|klientet"}]},{"id":"4|klientet"}]';
$old_menu = json_decode($menu, true);
$new_menu = check_recursive($old_menu);
function check_recursive($old_menu)
{
$new_menu = array();
foreach ($old_menu as $item) {
$name = check_menu($item['id']);
if($name){
$new_item = array(
'id' => $item['id'] . '|' . $name,
);
if(isset($item['children'])){
$new_item['children'] = check_recursive($item['children']);
}
$new_menu[] = $new_item;
}
}
return $new_menu;
}
function check_menu($string)
{
//Check if string exists in database
if ($string) {
return 'String exists';
}
return false;
}
Let me know if it suits your needs.
I'm constructing a gallery which will use the URI to define a set of filter settings. CodeIgniter's ruri_to_assoc() works brilliantly for the majority of my settings as they are as simple as key=>value. However, one value (tags) can contain a number of values that I wish to match against.
As ruri_to_assoc() works off a key/val pairing, how would I set an array to a key in the url? Example:
/days/365/order/oldest/tag/car/tag/red/tag/mustang
At the moment, it looks like I'm going to have to explode the uri_string() and cycle through it myself. Like so:
$test_fil = explode('/',$this->uri->uri_string());
unset($test_fil[0]);
$val = 'key';
foreach($test_fil as $fkey=>$fval){
if($fval=='tags'){
$val = 'tag';
$new_filter['tags'] = '';
}
else{
if($val == 'key'){
$new_filter[$fval] = '';
$val = 'val';
$current_key = $fval;
}
elseif($val == 'val'){
$new_filter[$current_key] = $fval;
$val = 'key';
}
else{
$new_filter['tags'][] = $fval;
}
}
}
Is there something in CI that can do this for me?
We just need to make sure that uri_to_assoc will not override already existing keys when building the array.
In application/core create MY_URI.php :
class MY_URI extends CI_URI
{
protected function _uri_to_assoc($n = 3, $default = array(), $which = 'segment')
{
if ( ! is_numeric($n))
{
return $default;
}
if (isset($this->keyval[$which], $this->keyval[$which][$n]))
{
return $this->keyval[$which][$n];
}
$total_segments = "total_{$which}s";
$segment_array = "{$which}_array";
if ($this->$total_segments() < $n)
{
return (count($default) === 0)
? array()
: array_fill_keys($default, NULL);
}
$segments = array_slice($this->$segment_array(), ($n - 1));
$i = 0;
$lastval = '';
$retval = array();
foreach ($segments as $seg)
{
/*HERE IS THE PART WE TRULY OVERRIDE*/
if ($i % 2)
{
if(is_array($retval[$lastval]))
$retval[$lastval][] = $seg;
else
$retval[$lastval] = $seg;
}
else
{
if(isset($retval[$seg]) && !is_array($retval[$seg]))
{
$tmp = $retval[$seg];
$retval[$seg] = array();
$retval[$seg][] = $tmp;
}
else if(!isset($retval[$seg]))
{
$retval[$seg] = NULL;
$lastval = $seg;
}
}
/*END OVERRIDE*/
$i++;
}
if (count($default) > 0)
{
foreach ($default as $val)
{
if ( ! array_key_exists($val, $retval))
{
$retval[$val] = NULL;
}
}
}
// Cache the array for reuse
isset($this->keyval[$which]) OR $this->keyval[$which] = array();
$this->keyval[$which][$n] = $retval;
return $retval;
}
}
And then in your controller, nothing change :
$myTags = $this->uri->uri_to_assoc();
Here is what I get after testing :
array (size=3)
'days' => string '365' (length=3)
'order' => string 'oldest' (length=6)
'tag' =>
array (size=3)
0 => string 'car' (length=3)
1 => string 'red' (length=3)
2 => string 'mustang' (length=7)
I just threw this together to help in debugging some PHP scripts. As you can see, it is sloppy but I am going to improve it some more.
My debug function has 2 variables passed in, a variable name and a variable value.
Is it possible to just pass in the variable and somehow get the name of the variable without manually doing it like I have it set now?
The Function
<?php
function debug($varname, $var)
{
echo '<br>' . $varname;
// $var is a STRING
if (is_string($var)) {
echo ' (string) = ' . $var . '<br>';
// $var is an ARRAY
} elseif (is_array($var)) {
echo ' (array) = <pre>';
print_r($var);
echo '</pre><br>';
// $var is an INT
} elseif (is_int($var)) {
echo ' (int) = ' . $var . '<br>';
// $var is an OBJECT
} elseif (is_object($var)) {
echo ' (object) = <pre>';
var_dump($var);
echo '</pre><br>';
}
}
The Test
$testString = 'just a test!';
$testArray = array(
'key1' => 'value1',
'key2' => 'value2',
'key3' => 'value3'
);
$testInt = 1234567890;
$testObject = new stdClass;
$testObject->someVar1 = 'testing123';
$testObject->someVar2 = '321gnitset';
debug('$testString', $testString);
debug('$testArray', $testArray);
debug('$testInt', $testInt);
debug('$testObject', $testObject);
?>
The Result...
$testString (string) = just a test!
$testArray (array) =
Array
(
[key1] => value1
[key2] => value2
[key3] => value3
)
$testInt (int) = 1234567890
$testObject (object) =
object(stdClass)#1 (2) {
["someVar1"]=>
string(10) "testing123"
["someVar2"]=>
string(10) "321gnitset"
}
If you want to know the name, why not just pass a string constant of the name of the variable, and use global array to access it (for procedural programs)
function foo($var) {
echo $var; //name of the variable
echo $GLOBALS[$$var]; //value of the variale
}
$bar = 'a string';
foo('bar');
Check out this php function func_get_arg()
Actually... it looks like you can't really do it... check this other question How to get a variable name as a string in PHP?
debug_print_backtrace() is your friend! Add it to your debug() function.
If you still want only the calling function name you can use debug_backtrace() and search in the returned array for the name of the previous function, identified as "function" in the associative array result!
I put together these functions for my own debugging just copy and save it in a separate file, include it and use the function d() to call the fancy debug print. it suppose to color code the results based on the type of variable passed.
if(!defined('m_debug')) {define('m_debug', 1);}
function d($var) {
if (m_debug) {
$bt = debug_backtrace();
$src = file($bt[0]["file"]);
$line = $src[ $bt[0]['line'] - 1 ];
//striping the inspect() from the sting
$strip = explode('d(', $line);
$matches = preg_match('#\(#', $strip[0]);
$strip = explode(')', $strip[1]);
for ($i=0;$i<count($matches-1);$i++) {
array_pop($strip);
}
$label = implode(')', $strip);
d_format($var, $label);
}
}
function l() {
global $super_dump_log;
if (func_num_args() > 0) {
$array = func_get_args();
array_merge($super_dump_log, $array);
} else {
foreach($super_dump_log as $log){
//
}
}
}
function d_format($var, $label) {
$colorVar = 'Blue';
$type = get_type($var);
$colorType = get_type_color($type);
echo "<div class='m_inspect' style='background-color:#FFF; overflow:visible;'><pre><span style='color:$colorVar'>";
echo $label;
echo "</span> = <span class='subDump' style='color:$colorType'>";
if ($type == 'string') {
print_r(htmlspecialchars($var));
} else {
print_r($var);
}
echo "</span></pre></div>";
}
function get_type($var) {
if (is_bool($var)) {
$type = 'bool';
} elseif (is_string($var)) {
$type = 'string';
} elseif (is_array($var)) {
$type = 'array';
} elseif (is_object($var)) {
$type = 'object';
} elseif (is_numeric($var)) {
$type = 'numeric';
} else {
$type = 'unknown';
}
return $type;
}
function get_type_color($type) {
if ('bool' == $type) {
$colorType = 'Green';
} elseif ('string' == $type) {
$colorType = 'DimGrey';
} elseif ('array' == $type) {
$colorType = 'DarkOrchid';
} elseif ('object' == $type) {
$colorType = 'BlueViolet';
} elseif ('numeric' == $type) {
$colorType = 'Red';
} else {
$colorType = 'Tomato';
}
return $colorType;
}
You can do this from the other end. Pass the variable name in a string variable and then call it with $$ to pass the actual variable. I made my_var_dump function:
function my_var_dump($varName, $var, $line = false, $func = false)
{
if ($func) $func = ' in function ' . $func;
if ($line) $line = ' at line ' . $line;
echo '<pre>DEBUG $' . $varName . $line . $func . PHP_EOL;
var_dump($var);
echo '</pre>' . PHP_EOL;
}
Call this function like this:
my_var_dump($varName = "some_var_name", $$varName, __LINE__, __FUNCTION__);
SOLUTION :
$argv — Array of arguments passed to script
EXAMPLE :
<?php
var_dump($argv);
?>
REFERENCE :
PHP's $argv documentation