echoing array from function in php - php

I am trying to create an array from a function.
The function:
$results = [];
function getDirEnties($directory, &$results) {
$entries = scandir($directory);
foreach ($entries as $item) {
if (!in_array($item, ['.', '..']) && substr($item, 0, 1) !== '.') {
$path = $directory . '/' . $item;
if (is_dir($path)) {
getDirEnties($path, $results);
} else {
$pathInfo = pathinfo($path);
$name = $pathInfo['filename'];
$type = 'unknown';
if (!empty($pathInfo['extension'])) {
$name .= "." . $pathInfo['extension'];
switch (strtolower($pathInfo['extension'])) {
case "gif":
case "jpg":
case "png":
case "jpeg":
case "bmp":
//etc..
$type = 'image';
break;
case "mp4":
$type = 'media';
break;
}
}
$data = [
'name' => $name,
'path' => $pathInfo['dirname'],
'type' => $type,
'time' => filemtime($path)
];
$results[] = $data;
}
}
}
return $results;
}
to populate the function I have the following:
$stmt=$db->prepare('SELECT friend2 as username FROM list_friends
WHERE (friend1 = :username AND friend2 <> :username)
UNION
SELECT friend1 as username FROM list_friends
WHERE (friend2 = :username AND friend1 <> :username)');
$stmt->bindParam(':username', $username);
$stmt->execute();
$friend_rows = $stmt->fetchAll();
foreach ($friend_rows as $rows) {
$friend = strtolower($rows['username']);
$directoryToScan = '/path/to/'.$friend;
$tree = getDirEnties($directoryToScan, $results);
}
I am then trying to echo it out as follows:
function cmp($a, $b) {
$ad = new DateTime($a['time']);
$bd = new DateTime($b['time']);
if ($ad == $bd) {
return 0;
}
return $ad < $bd ? -1 : 1;
}
if ($data !== NULL) {
usort($data, "cmp");
for($i=(count($data)-1)-($feed-1);$i>=(count($data)-10)-($feed-1);$i--){
if($data[$i]['type']=='image'){ echo $data[$i]['name']; }
}
}
I am JUST learning functions and have VERY limited experience with arrays, mostly with mysql arrays so I have no idea how to write this in such a way it returns the $data[] array properly as needed.

You inverted the use of $results and $data
Here you use your $results array as input/output :
$tree = getDirEnties($directoryToScan, $results);
Then later you try to print $data
if ($data !== NULL) {
usort($data, "cmp");
for($i=(count($data)-1)-($feed-1);$i>=(count($data)-10)-($feed-1);$i--){
if($data[$i]['type']=='image'){ echo $data[$i]['name']; }
}
}
But the way you written the code, all your needs are in $results. Use $results !
if ($results !== NULL) {
usort($results, "cmp");
for($i=(count($results)-1)-($feed-1);$i>=(count($results)-10)-($feed-1);$i--){
if($results[$i]['type']=='image'){ echo $results[$i]['name']; }
}
}

If you want to print the entire array, use this. print_r(array_values($ARR));

The answer I marked correct, basically laid out my answer for me although it wasn't "exactly" what I wanted in terms of code. Ultimately all I had to do was change my variables and output a touch.
$tree = getDirEnties($directoryToScan, $results);
to
$tree = getDirEnties($directoryToScan, $data);
then
echo $tree; // I can't believe I missed this
then
return $results;
to
return $data;
Finally because I am sorting times with usort I had to change
'time' => filemtime($path)
to
'time' => date('F d Y h:i A', (filemtime($path)))

Related

Sort multidimensional array by another array and complete missing keys in the same order

I'm trying to export data from leads table to excel using PHP/Laravel, the leads table caמ be customized to show specific columns and the export columns should be same as the table columns. the problem is - if column not exists in a specific row the column not shown empty and the 'xls' file is exported really messy...
my code looks like this:
public function excelExport(Request $request, $client_id=null)
{
$client_id = is_null($client_id) ? \Auth::client()->id : $client_id;
if(is_null($this->client_users)){
$this->client_users = $this->clientsController->listClientUsers($client_id);
}
$columns = $this->account_settings->getColumnsDef($client_id);
$query = Lead::select(array_keys($columns))->where('client_id',strval($client_id))->where('deleted',0);
$query = $this->setQueryDates($request,$query,$client_id);
$query = $this->leadsFiltersController->setExportQuery($request,$query);
$arr = $query->get()->toArray();
Excel::create('leads' , function($excel) use ($arr,$columns){
$excel->sheet('Leads' , function($sheet) use ($arr,$columns){
$rows = [];
$count = 0;
foreach($arr as $lead){
$row = $this->setExportRowData($lead,$count,$columns);
$rows[] = $row;
$count++;
}
$sheet->fromArray($rows);
});
})->export('xls');
private function setExportRowData($lead,$count,$columns,$order = true)
{
$row = [];
$order = null;
foreach($lead as $k => $v) {
if (is_array($v)) {
switch (strtolower($k)) {
case "ga_details":
if (count($v) > 2) {
foreach ($v as $key => $ga_detail) {
if ($key != "realTime_data" && $key != "uacid") {
$row[$key] = $ga_detail;
}
}
}
break;
case "status":
if (isset($v['name']) && count($v['name'])) {
$row['status'] = $v['name'];
} else {
$row['status'] = "no status";
}
break;
case "owner":
if (isset($v['owner_id']) && count($v)) {
$row['owner'] = $this->getClientOwnerUserName($this->client_users, $v['owner_id']);
} else {
$row['owner'] = "no owner";
}
break;
case "prediction":
if (isset($v['score']) && count($v)) {
$row['prediction'] = $v['score'];
} else {
$row['prediction'] = "no prediction";
}
break;
case "the_lead":
foreach ($v as $key => $lead_detail) {
$row[$key] = $lead_detail;
}
break;
case "quality":
if (isset($v['name'])) {
$row['quality'] = $v['name'];
} else {
$row['quality'] = "no quality";
}
break;
case "feeds":
if (isset($v['feeds']) && count($v['feeds'])) {
$row['feeds'] = array_pop($v['feeds'])['message'];
}
break;
default :
$row[$k] = $v;
break;
}
} else {
if ($k != "_id") {
$row[$k] = $v;
}
}
}
return $order == true ? sortArrayByArrayValues($this->order,$row) : $row;
}
sortArrayByArrayValues function looks like this:
function sortArrayByArrayValues(Array $array, Array $orderArray)
{
$rtn = [];
foreach($array as $arr){
if(isset($orderArray[$arr])){
$rtn[$arr] = $orderArray[$arr];
}else{
$rtn[$arr] = '';
}
}
return $rtn;
}
I really have no clue how to solve it, appreciate any help!!! :)

How to get both array key from value in 2 dimensional array (PHP)

$arr['animal'][0] = 'Dog';
$arr['animal'][1] = 'Cat';
From that array basically I need to create a function with the array value parameter and then it gives me the array keys.
For example:
find_index('Cat');
Output :
The result is animal, 1
You could probably do something like
function find_index($value) {
foreach ($arr as $index => $index2) {
$exists = array_search($value, $index2);
if ($exists !== false) {
echo "The result is {$index}, {$exists}";
return true;
}
}
return false;
}
Try this:
$arr['animal'][0] = 'Dog';
$arr['animal'][1] = 'Cat';
function find_index($searchVal, $arr){
return array_search($searchVal, $arr);
}
print_r(find_index('Cat', $arr['animal']));
Consider this Array,
$arr['animal'][] = 'Dog';
$arr['animal'][] = 'Cat';
$arr['insects'][] = 'Insect1';
$arr['insects'][] = 'Insect2';
Here is Iterator Method,
$search = 'InsectSub1';
$matches = [];
$arr_array = new RecursiveArrayIterator($arr);
$arr_array_iterator = new RecursiveIteratorIterator($arr_array);
foreach($arr_array_iterator as $key => $value)
{
if($value === $search)
{
$fill = [];
$fill['category'] = $arr_array->key();
$fill['key'] = $arr_array_iterator->key();
$fill['value'] = $value;
$matches[] = $fill;
}
}
if($matches)
{
// One or more Match(es) Found
}
else
{
// Not Found
}
$arr['animal'][] = 'Dog';
$arr['animal'][] = 'Cat';
$arr['insects'][] = 'Insect1';
$arr['insects'][] = 'Insect2';
$search_for = 'Cat';
$search_result = [];
while ($part = each($arr)) {
$found = array_search($search_for, $part['value']);
if(is_int($found)) {
$fill = [ 'key1' => $part['key'], 'key2' => $found ];
$search_result[] = $fill;
}
}
echo 'Found '.count($search_result).' result(s)';
print_r($search_result);

Multidimensional Array search by string

I have a multidimensional array that's contains all user data , and I've build a function to get array value with the given key .
the problem is that the array is multidimensional array , and I don't know how many level .
this is the function
function getUserSessionData($key)
{
$arrKeys = explode('.', $key);
if(count($arrKeys) == 1){
if(isset($_SESSION['user_data'][$arrKeys[0]])){
return $_SESSION['user_data'][$arrKeys[0]];
}
}
else{
if(isset($_SESSION['user_data'][$arrKeys[0]][$arrKeys[1]])){
return $_SESSION['user_data'][$arrKeys[0]][$arrKeys[1]];
}
}
return 0;
}
and this is an example of the call.
getUserSessionData('profile.firstName');
The (.) indicates of level of the array .
the function is support only tow levels .. is there any way to enhance this function so it can support more than tow levels ??
Sure, use a looping structure:
function getUserSessionData($key) {
$parts = explode('.', $key);
$data = $_SESSION["user_data"];
while (count($parts) > 0) {
$part = array_shift($parts);
$data = $data[$part];
}
return $data;
}
Or independently of the session:
function resolveKey($array, $key) {
$parts = explode('.', $key);
while (count($parts) > 0) {
$part = array_shift($parts);
$array = $array[$part];
}
return $array;
}
echo resolveKey(array(
"foo" => array(
"bar" => array(
"baz" => "ipsum"
)
)
), "foo.bar.baz"); // "ipsum"
echo resolveKey($_SESSION["user_data"], 'profile.firstName');
Here's a PHP-Fiddle
function getUserSessionData($key){
$arrKeys = explode('.', $key);
$data = $_SESSION['user_data'];
foreach($arrKeys as $k){
if(isset($data[$k])) $data = $data[$k];
else return false;
}
return $data;
}
Example usage:
session_start();
$_SESSION['user_data'] = [];
$_SESSION['user_data']['user'] = [];
$_SESSION['user_data']['user']['name'] = [];
$_SESSION['user_data']['user']['name']['first'] = "robert";
echo getUserSessionData("user.name.first"); // echos "robert"
Thank you #Halcyon
you've been very helpful.
but I've modified your function to get it to work .
this is the new function
function getUserSessionData($key) {
$data = Yii::app()->session['account_data']['user_data'];
$parts = explode('.', $key);
while (count($parts) > 0) {
$part = $parts[0];
if(!isset($data[$part])){
return 0;
}
$data = $data[$part];
array_shift($parts);
}
return $data;
}

PHP sort array by same value twice

I have array with show names like this:
$shows = array('morning_show_15_02_2014_part2.mp3',
'morning_show_15_02_2014_part1.mp3',
'morning_show_14_02_2014_part2.mp3',
'morning_show_14_02_2014_part1.mp3',
'morning_show_13_02_2014_part2.mp3',
'morning_show_13_02_2014_part1.mp3');
So the list look like:
morning_show_15_02_2014_part2.mp3
morning_show_15_02_2014_part1.mp3
morning_show_14_02_2014_part2.mp3
morning_show_14_02_2014_part1.mp3
morning_show_13_02_2014_part2.mp3
morning_show_13_02_2014_part1.mp3
This is what i get when i loop the directory.
But the list should look like this:
morning_show_15_02_2014_part1.mp3
morning_show_15_02_2014_part2.mp3
morning_show_14_02_2014_part1.mp3
morning_show_14_02_2014_part2.mp3
morning_show_13_02_2014_part1.mp3
morning_show_13_02_2014_part2.mp3
Still ordered by date, but part 1 is first and then comes part 2.
How can i get this list into right order?
Thank you for any help!
Resolved!
Code is prett nasty but i got what i was looking for:
public function getMp3ListAsJSONArray() {
$songs = array();
$mp3s = glob($this->files_path . '/*.mp3');
foreach ($mp3s as $key => $mp3Source) {
$mp3Source = basename($mp3Source);
$mp3Title = substr($mp3Source, 4);
$mp3Title = substr($mp3Title, 0, -4);
$mp3Title = basename($mp3Source, ".mp3");
$mp3Title = str_replace('_', ' ', $mp3Title);
$mp3Title = ucfirst($mp3Title);
$songs[$key]['title'] = $mp3Title;
$songs[$key]['mp3'] = urldecode($this->files_url . '/' . $mp3Source);
}
rsort($songs);
$pairCounter = 1;
$counter = 0;
foreach ($songs as $key => $value) {
$playlist[$pairCounter][] = $value;
$counter = $counter + 1;
if($counter == 2) {
$pairCounter = $pairCounter + 1;
$counter = 0;
}
}
foreach ($playlist as $show) {
$finalList[] = $show[1];
$finalList[] = $show[0];
}
$finalList = json_encode($finalList);
return $finalList;
}
Output is like i described in the topic.
Try to use array sort
Here is an example for you
http://techyline.com/php-sorting-array-with-unique-value/
You must definitely write your own string comparision function. Remember that you have 2 different comparisons. The first compares the first parts for the filenames as strings. The second part compares the numbers, where 20 comes after 2. This is a natural number sorting for the second part. The third part is after the last dot in the filename. This will be ignored.
<?php
function value_compare($a, $b) {
$result = 0;
$descending = TRUE;
$positionA = strpos($a, 'part');
$positionB = strpos($b, 'part');
if ($positionA === $positionB) {
$compareFirstPart = substr_compare($a, $b, 0, $positionA + 1);
if ($compareFirstPart === 0) {
$length = 0;
$offset = $positionA + strlen('part');
$positionDotA = strrpos($a, '.');
$positionDotB = strrpos($b, '.');
$part2A = '';
$part2B = '';
if ($positionDotA !== FALSE) {
$part2A = substr($a, $offset, $positionDotA);
} else {
$part2A = substr($a, $offset);
}
if ($positionDotB !== FALSE) {
$part2B = substr($b, $offset, $positionDotB);
} else {
$part2B = substr($b, $offset);
}
$result = strnatcmp($part2A, $part2B);
} else {
$result = $compareFirstPart;
if ($descending) {
$result = -$result;
}
}
}
return $result;
}
$shows = array('morning_show_15_02_2014_part2.mp3', 'morning_show_15_02_2014_part1.mp3', 'morning_show_14_02_2014_part2.mp3', 'morning_show_14_02_2014_part1.mp3', 'morning_show_13_02_2014_part2.mp3', 'morning_show_13_02_2014_part1.mp3');
usort($shows, 'value_compare');
var_dump($shows);
?>

How to sort file name from a folder order by create date by php?

How to sort file name from a folder order by create date by php?
$filesname = dirname(__FILE__) . '/../tmp/20120123/';
foreach(glob($filesname) as $files){
echo $files.'<br />';
}
Try this function I wrote for just such a task:
// Constants to make usage more reader-friendly
define('DIR_SORT_NAME', 1);
define('DIR_SORT_SIZE', 2);
define('DIR_SORT_ATIME', 3);
define('DIR_SORT_MTIME', 4);
define('DIR_SORT_CTIME', 5);
function readdir_sorted_array ($dir, $sortCol = DIR_SORT_NAME, $sortDir = SORT_ASC) {
// Validate arguments
$dir = rtrim(str_replace('\\', '/', $dir), '/');
$sortCol = (int) ($sortCol >= 1 && $sortCol <= 5) ? $sortCol : 1;
$sortDir = ($sortDir == SORT_DESC) ? SORT_DESC : SORT_ASC;
$name = $size = $aTime = $mTime = $cTime = $table = array();
// Open the directory, return FALSE if we can't
if (!is_dir($dir) || (!$dp = opendir($dir))) return FALSE;
// Fetch a list of files in the directory and get stats
for ($i = 0; ($file = readdir($dp)) !== FALSE; $i++) {
if (!in_array($file, array('.','..'))) {
$path = "$dir/$file";
$row = array('name'=>$file,'size'=>filesize($path),'atime'=>fileatime($path),'mtime'=>filemtime($path),'ctime'=>filectime($path));
$name[$i] = $row['name'];
$size[$i] = $row['size'];
$aTime[$i] = $row['atime'];
$mTime[$i] = $row['mtime'];
$cTime[$i] = $row['ctime'];
$table[$i] = $row;
}
}
// Sort the results
switch ($sortCol) {
case DIR_SORT_NAME:
array_multisort($name, $sortDir, $table);
break;
case DIR_SORT_SIZE:
array_multisort($size, $sortDir, $name, SORT_ASC, $table);
break;
case DIR_SORT_ATIME:
array_multisort($aTime, $sortDir, $name, SORT_ASC, $table);
break;
case DIR_SORT_MTIME:
array_multisort($mTime, $sortDir, $name, SORT_ASC, $table);
break;
case DIR_SORT_CTIME:
array_multisort($cTime, $sortDir, $name, SORT_ASC, $table);
break;
}
// Return the result
return $table;
}
Hopefully usage is fairly self-explanatory.

Categories