Convert array and object with HTML entities - php

I am trying to write a piece of code, that will recursively convert every string in an array or object to be safe with the quotes for displaying in input boxes.
This is an array I wrote, with parts I have seen from other peoples. And it works for objects but not arrays, it seems to get to the second array, and outputs a string "null"
function fixQuotes($item)
{
if (is_object($item)) {
foreach (get_object_vars($item) as $property => $value) {
//If item is an object, then run recursively
if (is_array($value) || is_object($value)) {
fixQuotes($value);
} else {
$item->$property = htmlentities($value, ENT_QUOTES);
}
}
return $item;
} elseif (is_array($item)) {
foreach ($item as $property => $value) {
//If item is an array, then run recursively
if (is_array($value) || is_object($value)) {
fixQuotes($value);
} else {
$item[$property] = htmlentities((string)$value, ENT_QUOTES);
}
}
}
}

It was not saving the array if it was two arrays deep, it is now working, also it was missing the return on the array. Thanks for reading it.
Here is a copy of the fixed code if someone in future needs a script that does this.
function fixQuotes($item)
{
if (is_object($item)) {
foreach (get_object_vars($item) as $property => $value) {
//If item is an object, then run recursively
if (is_array($value) || is_object($value)) {
$item->$property = fixQuotes($value);
} else {
$item->$property = htmlentities($value, ENT_QUOTES);
}
}
return $item;
} elseif (is_array($item)) {
foreach ($item as $property => $value) {
//If item is an array, then run recursively
if (is_array($value) || is_object($value)) {
$item[$property] = fixQuotes($value);
} else {
$item[$property] = htmlentities((string)$value, ENT_QUOTES);
}
}
return $item;
}
}

Related

Search inside multidimensional array and return other key value

I have the following
Multidimensional array.
What I'm trying to do is to search for an IDITEM value and if it's found, return the value of the "PRECO" key.
I'm using the following function to check if the value exists and it works fine, but I can't find a way to get the "PRECO" value of the found IDITEM.
Function:
function search_array($needle, $haystack) {
if(in_array($needle, $haystack)) {
return true;
}
foreach($haystack as $element) {
if(is_array($element) && search_array($needle, $element))
return true;
}
return false;
}
Anyone can help me with that?
You can change the first if statement to return it instead of returning a boolean :
function search_array($needle, $haystack) {
if(in_array($needle, $haystack) && array_key_exists('PRECO', $haystack)) {
return $haystack['PRECO'];
}
foreach($haystack as $element) {
if(is_array($element))
{
$result = search_array($needle, $element);
if($result !== false)
return $result;
}
}
return false;
}
The easiest idea I can remember is converting that boolean search_array into a path creator, where it will return the path for the item, or false if it isn't found.
function get_array_path_to_needle($needle, array $haystack)
{
if(in_array($needle, $haystack))
{
return true;
}
foreach($haystack as $key => $element)
{
if(is_array($element) && ($path = get_array_path_to_needle($needle, $element)) !== false)
{
return $path === true ? $key : $key . '.' . $path;
}
}
return false;
}
Then, since you already have the path, then rerun the array to fetch the item
function get_array_value_from_path(array $path, array $haystack)
{
$current = $haystack;
foreach($path as $key)
{
if(is_array($current) && array_key_exists($key, $current))
{
$current = $current[$key];
}
else
{
return false;
}
}
return $current;
}
This wont get you the PRECO, but it will return the item (array) where id found the value you searched for.
So a simple usage would be:
$path = get_array_path_to_needle('000000000000001650', $data);
$item = get_array_value_from_path(explode('.', $path), $data);
// here you have full array for that item found
print_r($item);
// here you have your price
print_r($item['PRECO']);
Use a static variable to remember the status between multiple function calls, and also to store the desired PRECO value. It makes the function remember the value of the given variable ($needle_value in this example) between multiple calls.
So your search_array() function should be like this:
function search_array($needle, $haystack){
static $needle_value = null;
if($needle_value != null){
return $needle_value;
}
foreach($haystack as $key => $value){
if(is_array($value)){
search_array($needle, $value);
}else if($needle == $value){
$needle_value = $haystack['PRECO'];
break;
}
}
return $needle_value;
}
This function will finally return $needle_value, which is your desired PRECO value from the haystack.
The simplest way is to use a foreach loop twice. Check for the key and store the result into an array for later use.
Based on your array, the below
$search = '000000000000001650';
foreach($array as $element){
foreach ($element['ITEM'] as $item){
if (isset($item['IDITEM']) and $item['IDITEM'] == $search){
$results[] = $item['PRECO'];
}
}
}
print_r($results);
Will output
Array
(
[0] => 375
)
Here is the simple example with array:
// your array with two indexes
$yourArr = array(
0=>array(
'IDDEPARTAMENTO'=>'0000000001',
'DESCRDEPT'=>'Área',
'ITEM'=>
array(
array(
'SETID'=>'RX',
'IDITEM'=>'000000000000001367',
'DESCRITEM'=>'PISTA TESTE DRIV',
'PRECO'=>'1338.78'),
array(
'SETID'=>'RX',
'IDITEM'=>'000000000000001925',
'DESCRITEM'=>'PISTA TESTE DRIV2',
'PRECO'=>'916'),
)
),
1=>array(
'IDDEPARTAMENTO'=>'0000000010',
'DESCRDEPT'=>'Merch',
'ITEM'=>
array(
array(
'SETID'=>'RX',
'IDITEM'=>'000000000000002036',
'DESCRITEM'=>'PISTA TESTE DRIV23',
'PRECO'=>'200.78'),
array(
'SETID'=>'RX',
'IDITEM'=>'000000000000001608',
'DESCRITEM'=>'PISTA CRACHÁ DRIV4',
'PRECO'=>'44341'),
)
));
// solution
$newArr = array();
foreach ($yourArr as $value) {
foreach ($value as $key => $innerVal) {
if($key == 'ITEM'){
foreach ($innerVal as $key_inner => $keyinner) {
if(!empty($keyinner['IDITEM'])){
$newArr[$keyinner['IDITEM']] = $keyinner['PRECO'];
}
}
}
}
}
echo "<pre>";
print_r($newArr);
Result values with IDITEM:
Array
(
[000000000000001367] => 1338.78
[000000000000001925] => 916
[000000000000002036] => 200.78
[000000000000001608] => 44341
)

Illegal Offset Type Error

So I've got the following function:
function sitesync_empty_vals(&$entity) {
$vals = false;
$entity = (array) $entity;
foreach ($entity as $field) {
if (is_array($field)) {
foreach ($field as $lang) {
foreach ($lang as $item) {
if (isset($item['value'])) {
if (empty($item['value'])) {
unset($field[$lang][$item]);
break;
}
else {
$vals = true;
}
}
}
}
if (!$vals && is_array($lang)) {
watchdog("field", print_r($field, true));
unset($field[$lang]);
}
}
}
}
I keep getting the error Illegal offset type.
I'm not quite understanding why I'd be getting this error - it seems to be related to unsetting the $field[$lang][$item] (I don't get the error when I comment it out), but why would that be? Is it because it's trying to iterate over that item after it is unset? In the case that that particular value is empty, I want to unset the whole $item - this is for data normalization between two different servers, one of which doesn't store any data, and one of which stores the data as a 0.
foreach ($lang as $item) {
^^^^---array
unset($field[$lang][$item]);
^^^^^---using Array as array key
You probably want something more like:
foreach($lang as $lang_key => $item) {
unset($field[$lang_key]....);
instead. And as the comments below have noted, $item is ALSO an array, so you'll want a similar treatment for that as well.
Here is a quote from the PHP Docs:
Arrays and objects can not be used as keys. Doing so will result in a warning: Illegal offset type.
http://www.php.net/manual/en/language.types.array.php
You have to use the keys, not the arrays themselves:
function sitesync_empty_vals(&$entity) {
$vals = false;
$entity = (array) $entity;
foreach ($entity as $field) {
if (is_array($field)) {
foreach ($field as $langKey=>$lang) {
foreach ($lang as $itemKey=>$item) {
if (isset($item['value'])) {
if (empty($item['value'])) {
unset($field[$langKey][$itemKey]);
break;
}
else {
$vals = true;
}
}
}
}
if (!$vals && is_array($lang)) {
watchdog("field", print_r($field, true));
unset($field[$langKey]);
}
}
}
}

Why "return" on PHP function is not stopping the process?

I do not understand why "return" is not stopping the process in this function that I created to search a value on a multi_level array in PHP.
This is the code:
static function in_array_multi($needle, $haystack) {
foreach ($haystack as $item) {
if(is_array($item)){
in_array_multi($needle, $item);
}
else{
if ($item === $needle) {
return "ok";
}
}
}
return "nok";
}
I am using this array as exemple:
$arr = array(0 => array(id=>1,name=>"cat 1"),
1 => array(id=>2,name=>"cat 2"),
2 => array(id=>3,name=>array(id=>7,name=>"cat 7"))
);
And I am calling the function like this:
echo in_array_multi("cat 1",$arr);
It is returning "nok".
I am using xdebug to follow the process. It should stop the process on the second round.
Someone has any idea about what is happening?
Thanks
My comment was a bit careless. You would only want to return directly from the recursion if the recursion actually finds the value. You could do
function in_array_multi($needle, $haystack) {
foreach ($haystack as $item) {
if(is_array($item)){
if ('ok' === in_array_multi($needle, $item)) {
return 'ok';
}
}
elseif ($item === $needle) {
return "ok";
}
}
return "nok";
}
Because you make the return of function will stop the loop, you should collect it and return in the final.
Maybe you want this..
function array_multiple_search($array, $key, $value=null) {
$return = array();
if (is_array($array)) {
if (isset($array[$key])) {
if (is_null($value)) {
$return[] = $array;
} elseif ($array[$key] == $value) {
$return[] = $array;
}
}
foreach ($array as $subarray) {
$return = array_merge($return, array_multiple_search($subarray, $key, $value));
}
}
return $return;
}
param 1 is the target array
param 2 is the key you want to search of target array
param 3 is the value you want to search with the key of target array(can null)
This function will collect and return an array of qualified.

Failing to recursively filter multidimensional array of objects

I have a variable which may be an object or an array. If it is an array, it will be of objects. Each object may have a parameter which is another object or an array of objects. All arrays may be n levels deep.
All objects have a parameter 'isAccessible'. The value of this parameter may be true or false.
If it is false, that object must be removed from the structure.
I have tried array_filter and because I was not able to recursively filter as described, I have written a home rolled recursion function.
However I have not been able to get it to work. Here is my code:
public static function jsonGateway($json) {
$object = json_decode($json);
$newJSON = '';
// $object may be a stdClass Object or it may be an array of stdClass Objects
// An objects parameters may be a string, integer, or an array of stdClass Objects.
// This function must recurse arbitrarily deep
// Any object where isAccessible = 0 must be purged (numeric string or int?)
if (is_object($object)) {
if ($object->isAccessible == 1 || $object->isAccessible == '1' || $object->isAccessible == true) {
$newJSON = $json;
}
} else if (is_array($object)) {
$newJSON = json_encode(self::filterRecursive($object));
}
echo $newJSON;
}
public static function filterRecursive(Array $source) {
$result = array();
foreach ($source as $key => $value) {
if (is_object($value)) {
$object = $value; // Just a comprehension aid
if ($object->isAccessible == 1 || $object->isAccessible == '1' || $object->isAccessible == true) {
// Keep this object
// This objec though, may have a parameter which is an array
// If so, we need to recurse
$objectVars = get_object_vars($object);
if (count($objectVars) > 0) {
foreach ($objectVars as $objectParameter => $objectValue) {
if (is_object($objectValue)) {
if ($object->isAccessible == 1 || $object->isAccessible == '1' || $object->isAccessible == true) {
$object[$objectParameter] = $objectValue;
}
} else if (is_array($objectValue)) {
$object[$objectParameter] = self::filterRecursive($objectValue); // Line 177
}
}
}
$result[$key] = $object;
} else {
// don't need this block
error_log("deleting: " . print_r($object,true));
}
}
if (is_array($value)) {
$array = $value; // Just a comprehension aid
$result[$key] = self::FilterRecursive($array);
continue;
}
}
return $result;
}
Not only am I not succeeding at filtering anything, I am getting the following error:
PHP Fatal error: Cannot use object of type stdClass as array in /home1/lowens/public_html/dev/classes/Lifestyle/RBAC.php on line 177
Can you help?
Solution:
/**
* #param array $array
* #return array
*/
public static function filterArray(Array $array) {
$result = array();
foreach ($array as $key => $value) {
if (is_object($value)) {
$newObject = self::filterObject($value);
if (count(get_object_vars($newObject)) > 0) {
$result[$key] = $newObject;
}
} else if (is_array($value)) {
$newArray = self::filterArray($value);
if (count($newArray) > 0) {
$result[$key] = $newArray;
}
} else {
$result[$key] = $value;
}
}
return $result;
}
/**
* #param \stdClass $object
* #return \stdClass
*/
public static function filterObject(\stdClass $object) {
$newObject = new \stdClass();
if ($object->isAccessible == 1) {
$objectVars = get_object_vars($object);
foreach ($objectVars as $objectParameter => $objectValue) {
if (is_object($objectValue)) {
$newObject->$objectParameter = self::filterObject($objectValue);
} else if (is_array($objectValue)) {
$newObject->$objectParameter = self::filterArray($objectValue);
} else {
$newObject->$objectParameter = $objectValue;
}
}
}
return $newObject;
}

PHP looping multidimensional array

Not entirely sure how to adequately title this problem, but it entails a need to loop through any array nested within array, of which may also be an element of any other array - and so forth. Initially, I thought it was required for one to tag which arrays haven't yet been looped and which have, to loop through the "base" array completely (albeit it was learned this isn't needed and that PHP somehow does this arbitrarily). The problem seems a little peculiar - the function will find the value nested in the array anywhere if the conditional claus for testing if the value isn't found is omitted, and vice versa. Anyway, the function is as followed:
function loop($arr, $find) {
for($i=0;$i<count($arr);$i++) {
if($arr[$i] == $find) {
print "Found $find";
return true;
} else {
if(is_array($arr[$i])) {
$this->loop($arr[$i], $find);
} else {
print "Couldn't find $find";
return false;
}
}
}
}
Perhaps you should change your code to something like:
var $found = false;
function loop($arr, $find) {
foreach($arr as $k=>$v){
if($find==$v){
$this->found = true;
}elseif(is_array($v)){
$this->loop($v, $find);
}
}
return $this->found;
}
This has been working for me for a while.
function array_search_key( $needle_key, $array ) {
foreach($array AS $key=>$value){
if($key == $needle_key) return $value;
if(is_array($value)){
if( ($result = array_search_key($needle_key,$value)) !== false)
return $result;
}
}
return false;
}
OK, what about a slight modification:
function loop($arr, $find) {
for($i=0;$i<count($arr);$i++) {
if(is_array($arr[$i])) {
$this->loop($arr[$i], $find);
} else {
if($arr[$i] == $find) {
print "Found $find";
return true;
}
}
}
return false;
}
Hmm?
Try this: PHP foreach loop through multidimensional array

Categories