I am writing a recursive function to print out the differences between 2 multildimensional php arrays. The purpose of this code is to see the difference between jpeg headers to deteremine how adobe bridge cs3 is saving rating information within the jpg file.
When I am single-stepping through the code using my eclipse - zend debugger ide, it appears that even though the initial if statement is false (ie neither values is an array), the subsequent elseif statements are never executed. The function is attached below.
Note: Changes since original post based on comments
Added a default level= ''
Removed comments between the if{} elseif{} blocks
Removed an else; at the end of the block that had no function
Encoded the < and > symbols so angle bracket would show in my code
function array_diff_multi($array1,$array2,$level=''){
$keys = array_keys($array1);
foreach($keys as $key)
{
$value1 = $array1[$key];
if(array_key_exists($key,$array2) ){
$value2 = $array2[$key];
if (is_array($value1) && is_array($value2)){ // Check if they are both arrays, if so recursion is needed
array_diff_multi($value1,$value2,$level . "[ " . $key . " ]");
}
elseif(is_array($value1) != is_array($value2)){ // Recursion is not needed, check if comparing an array to another type
print "<br>" . $level . $key ."=>" . $value1 . "as array, compared to ". $value2 ."<br>";
}
elseif($value1 != $value2){ // the values don't match, print difference
print "<br>" . $level . $key ."=>" . $value1 ." != " . $value2 ."<br>";
}
}
else{
print "<br>" . $level. $key . "does not exist in array2";
}
}
}
could it be because you have
else;
at the end...?
Try removing that or turning that into 'real code'
It works fine for me here. I put your function (with the tiny difference of adding a default value of '' to the level parameter), and these two arrays:
$a1 = array('foo', 'bar', 2, array('baz', '3', 4, array(54,45)));
$a2 = array('faz', 'bar', 4, array('buz', '3', 5, 54));
And got this output:
0=>foo != faz
2=>2 != 4
[ 3 ]0=>baz != buz
[ 3 ]2=>4 != 5
[ 3 ]3=>Arrayas array, compared to 54
Perhaps your starting arrays are not what you think they are...?
This doesn't exactly answer your question, but I think Adobe Bridge saves metadata in dotfiles in the same directory as the files. For example, sort information is saved in a .bridgesort file.
The only way that all the elseifs would be skipped is if the two variables are not arrays and are equal.
Related
I was asked to create simulation array_keys function, but check equality "==" returns false.
But with "strcmp ($a, $b) == 0" return true.
class Utility
{
public function convertArrayKeys(array $array)
{
$i = 0;
$elements = [];
foreach ($array as $element=>$value) {
$elements[] = ' ' . $i++ . " => '" . $element . "'";
}
return 'array ( ' . implode(', ', $elements) . ', )';
}
public function testStrings(array $array)
{
$arrayOur = $this->convertArrayKeys($array);
$arrayPhp = var_export(array_keys($array),true);
if ($arrayOur == $arrayPhp){
echo 'They are identical :)';
} else {
echo 'They are not identical :(';
echo '<br>';
print_r(str_split($arrayOur));
echo '<br>';
print_r(str_split($arrayPhp));
}
}
}
View:
$repository = array('box'=>'blue', 'cube'=>'red', 'ball'=>'green');
$utility = new Utility();
echo "OUr array_keys: ";
echo $utility->convertArrayKeys($repository);
echo "<br />";
echo "PHP array_keys: ";
print_r (var_export(array_keys($repository)));
echo "<hr >";
echo "<br />";
echo $utility->testStrings($repository);
I would appreciate to know because
Edit: The reason that the two don't work in THIS instance is that your functions dont produce identical outputs: yours produces:
array ( 0 => 'box', 1 => 'cube', 2 => 'ball', )
where the php function produces:
array (
0 => 'box',
1 => 'cube',
2 => 'ball',
)
If you were to view that in the web browser i think the web browser renderer does whitespace trickery. However try putting uhh <pre> tags around it (or run in command line to check).
Basically == does more then compare the two values - the documentation suggests "after type juggling". You can get some weird things by comparing strings using ==. One good example is: '1e3' == '1000'. It is useful to use ==at times, but possibly not in conjunction with strings.
Strcmp also though doesn't return a true/false answer, but a -1, 0, 1 answer indicating which string is alphabetically in front of the other.
You should also look at === which can also have helpful uses, but personally I would stick with strcmp with strings.
Hi never use == in PHP. It will not do what you expect. Even if you are comparing strings to strings, PHP will implicitly cast them to floats and do a numerical comparison if they appear numerical.
try these you will know the reason
$something = 0;
echo ('password' == $something) ? 'true' : 'false';// true
$something = 0;
echo ('password' === $something) ? 'true' : 'false'; // false
echo strcmp('password123',$something); // 1
Because they are not arrays, rather they are strings. Arrays are not created like this. you are doing it wrong. Were they arrays then
if ($arrayOur == $arrayPhp)
would have evaluated to true. But they are just strings and
"strcmp ($a, $b) == 0"
Does not return true, because there are whitespaces in the first string,
return 'array ( ' . implode(', ', $elements) . ', )';
You are doing it completely wrong. You need to correct your approach.
The code below has two commented-out variations on one line. They produce rather different results, as you'll see if run them - without the space between $array and [$key], the individual letters of the key are mapped out to the array values.
Can someone explain what's happening here and why?
Thanks!
<?php
$letters = array('A','B','C');
$numbers = array(1,2,3);
$matrix = array('Letter' => $letters, 'Number' => $numbers);
foreach($matrix as $array => $list)
{
echo '<ul>';
foreach($list as $key => $value)
// {echo "<li>$array [$key] = $value ";}
// {echo "<li>$array[$key] = $value ";}
echo '</ul>';
}
"$array[$key]" is interpreted as the array access (value of $array[$key]). Same as echo $array[$key];.
"$array [$key]" is interpreted as two different variables: $array and $key. Same as echo $array." [".$key."]";.
The reason for the difference in output is due to the way that PHP parses strings containing variables.
If you change:
{echo "<li>$array [$key] = $value ";}
to
{echo "<li>" . $array [$key] . " = $value ";}
It will result in the same thing and the line below it.
{echo "<li>$array[$key] = $value ";}
PHP is mostly whitespace agnostic, but not inside of strings where intrinsically whitespace matters.
remember that "double quotes" tries to execute your code, while "single quotes" deals your code as text only.
in this case:
echo "<li>$array[$key] = $value ";
this code is being evaluated. here is saying something like "put this value in this position of this array". in the other hand, this:
echo "<li>$array [$key] = $value ";
isn't being evaluated because, to php, doens't make sense to it's parser assign a value to something like this:
[$someting] = $value;
the above code returns a fatal error.
your code doesn't return a fatal error because php tries to handle your code in some way that doesn't throw an exception.
the last example of your code (the one with spaces) is the same as this:
echo '<li>' . $array . '[' . $key . '] = ' . $value;
in short: want to show some variable in some string? put the variables off the php string's interpretation:
echo $myvar . ' = ' . $myvalue;
I have two arrays like this.
$array1=array(1,2,3,4,5,7);
$array2=array(1,2,3,4,5,6);
So, the output should bring the difference in both arrays.
The output should be.
1,2,3,4,5 -> These numbers exist in both arrays, so these should be ignored.
7 and 6 -> These numbers are the un-common in both arrays, so I need these values in array.
The output should be 7 & 6.
Help me out. I have tried array_diff and other array elements.
try this
array_merge(array_diff($array1,$array2),array_diff($array2,$array1))
foreach($array1 as $key => $value) {
if($value != $array2[$key]) {
echo "\$array1[" . $key . "] (" . $value . ") is different to \$array2[" . $key . "] (" . $array2[$key] . "<br />";
}
}
I would like to add stuff out of an array and translate them. However, some items in the array I do not want to translate and so encapsulate them into special tags. In this example i've uset < > but if you have suggestions/better iead's I'm open to them. I also thought of { } or [ ] and * * whichever you think is easiest.
<?php
# define the contents of my all time clients
$clients = array('<UNESCO>', 'Vrije Universiteit medical center');
# randomization engine
$keys = array_rand($clients, 3); // get 3 random keys from your array
foreach ($keys as $key) { // cycle through the keys to get the values
# if this item is inbetween < > tags..
if #??#######??########??#########??########??##
# then put this item directly into randomList without translation
$randomList .= "• " . $clients[$key]) . "<br/>"; // WORKS
# all other items without <tags> are first translated via __() then added
else $randomList .= "• " . __($clients[$key]) . "<br/>"; // WORKS
}?>
Question: What should be on line 10 to make the IF statement complete?
In other words, what is the logic in programming code that can match an item in the array being one of those special words that should not be translated and treaded differently?
Few possible solutions:
if (preg_match('~^<.*>$~', $clients[$key]))
if (strlen($clients[$key]) > 0 && $clients[$key][0] == '<' && substr($clients[$key], -1) == '>')
You probably want to ditch the brackets before outputting the name. You could use this then:
// note that you need to test against $clients[ $key ], not $key
if( preg_match( '~^<(.*)>$~', $clients[ $key ], $matches ) )
{
$randomList .= "• " . $matches[ 1 ] . "<br/>";
}
For some reason when an array has for example, four values it will display all four values four times I just want the values to be displayed one time.
How can I fix this problem? Note the first echo works perfectly.
Here is the code.
if (count($array) == 1){
echo $array[$x] . " one value has been entered";
} else {
echo implode(", ", $array) ." you entered more then one value;
}
Because $x obviously isn't the index of the first element of the array. Use the correct index. Or if you don't know what it is, just use reset():
if (count($array) == 1) {
echo reset($array) . ' one value has been entered';
} else {
echo implode(', ', $array) . ' you entered more than one value';
}
It might be helpful to dump the array to see what it actually contains:
print_r($array);
$x is not set in your code or just meaningless. If you have just one array item you can print it with the simple echo $array[0];