PHP getting all files into array issue - php

I have an small piece of PHP code that needs to put every file in the current directory into an array.
I have done this by making reading the dir with glob() and when it meets another dir it will loop.
My code I have as of now:
<?php
$find = '*';
$result = array();
function find($find)
{
foreach (glob($find) as $entry)
{
$result[] = $entry;
echo $entry.'<br>';
if (is_dir($entry)){
$zoek = ''.$entry.'/*';
find($zoek);
}
}
return $result;
}
print_r(find($find));
?>
When I execute the code the echo print exactly what I want. But the printed array doesn't give me the values I want, it only gives the values in the first dir it will come by then it seems to stop adding the value in the array.
What am I doing wrong?

You need to actually preserve the results you produce in the recursive callings to your function:
<?php
function listNodesInFolder($find) {
$result = [];
foreach (glob($find) as $entry) {
$result[] = $entry;
if (is_dir($entry)) {
$result = array_merge($result, find($entry.'/*'));
}
}
return $result;
}
print_r(find('*'));
Once on it I also fixes a few other issues with your code:
$result should be declared as an array inside your function, that that even if it does not loop you still return an array and not something undefined.
indentation and location of brackets got adjusted to general coding standards, that makes reading your code much easier for others. Get used to those standards, it pays out, you will see.
no need for an extra variable for the search pattern inside the conditional.
a speaking name for the function that tells what it actually does.
you should not name variables and functions alike ("find").

You need to add the result of find() to the array
Edit added array_merge - Cid's idea
<?php
$find = '*';
function find($find)
{
$result = array();
foreach (glob($find) as $entry)
{
$result[] = $entry;
echo $entry.'<br>';
if (is_dir($entry)){
$zoek = ''.$entry.'/*';
$result = array_merge($result, find($zoek));
}
}
return $result;
}
print_r(find($find));
?>

Related

Cannot redeclare function previously declared php

I'm running into an "Cannot redeclare" error and I can't figure out how to fix it. So I have a few functions in a php file located below. Now these functions iterate over an array of data.
I think I've surmised that the problem is that I'm looping the function over and over again in the foreach loop, and its the foreach loop thats been the problem. It seems like its already writing one the function to memory the first time and then for some reason it doesn't like being evoked again.
Your help appreciated.
P.S I've seen a number of similar posts on the issue such as Fatal error: Cannot redeclare but that doesn't seem to work.
<?php
// *****Code Omitted from Stack****
function postHelper($data, $field1, $field2)
{ //TODO Abstract and make sure post Helper and modify Post can be the same thing.
$result = array();
for ($j = 0; $j < count($data); ++$j) { //iterator over array
if ($field2 == "") {
$result[$j] = $data[$j][$field1];
} else {
return $result[$j] = $data[$j][$field1][$field2];
}
}
return $result;
}
//returns an array with only # and # values
function modifyPost($data)
{
//puts symbol # before read data
function addSymbol($data, $field1, $field2)
{
$info = postHelper($data, $field1, $field2);
foreach ($info as &$n) {
$n = '#' . $n;
}
print_r($info);
}
/*
Parse texts and returns an array with only # or # signs used
*/
function parseText($data)
{
$newarr = array();
$text = postHelper($data, "text", "");
foreach ($text as &$s) { //separates into words
$ex = explode(" ", $s);
foreach ($ex as &$n) { //if text doesnt' begin with '#' or '#' then throw it out.
if (substr($n, 0, 1) === '#' || strpos($n, '#') !== false) {
array_push($newarr, $n . ',');
}
}
}
return $newarr;
}
}
foreach ($posts as $entry) {
if (!function_exists('modifyPost')) {
$nval = "hello";
modifyPost($entry);
$entry['mod_post'] = $nval;
}
}
?>
EDIT: I've solved the error. Turns out that the original posts did actually work. I messed in naming. I will give points to anyone who can explain to me why this is necessary for a call. Moreover, I will update post if there is an additional questions that I have.
Php doesn't support nested functions. Although you technically can declare a function within a function:
function modifyPost($data)
{
function addSymbol($data, $field1, $field2)
the inner function becomes global, and the second attempt to declare it (by calling the outer function once again) will fail.
This behaviour seems counter-intuitive, but this is how it works at the moment. There's RFC about real nested functions, which also lists several workarounds for the problem.
The error says it all. You have duplicate modifyData() & parseText functions.
Remove the top half of the php file so only one of each occurs.

If true use foreach loop, else use while

I'm trying to link the MySQL while loop into foreach loop using something like this :
if($something == true){
foreach($array as $arr){
} else {
while($row = mysql_fetch_array($mysql_query)){
}
// loop instructions
}
It looks so wrong, I know but you see what I am trying to do ?.. I want to grab data from array if $something was true, else then grab data from database
I had another solution idea and its to manually match the array with how $mysql_query works so I can use them both with while only, something like this :
if($something == true){
$mysql_query = array("username" => "$_GET['username']", "password" => "$_GET['password']");
} else {
$mysql_query = mysql_query("SELECT * FROM users WHERE usern......");
}
while($row = mysql_fetch_array($mysql_query)){
...
That's a second way to do it but it looks wrong as well because the first array is normal, I want to match that normal array with how mysql_query builds it so it can fit with the while loop
P.S. : I DO NOT want to repeat writing the loop instructions, I want them both to work with only one like I mentioned above
Put your processing into a function:
function process_data($data) {
// do stuff
}
if($something){
foreach($array as $arr){
process_data($arr);
}
} else {
while($row = mysql_fetch_array($mysql_query)){
process_data($row);
}
}
The other answers here are fine, but you'd be better served just to make sure that $array is a valid array regardless of something ... How about
if (!something){
$array = array();
while($row=mysql_fetch_array($mysql_query)) {$array[] = $row;}
}
foreach($array as $arr){
// do work
}
You'd probably get a better answer if you expanded the scope of what you've explained a bit. Without knowing what the something is and what the data is, plus the ultimate objective then it's hard to tell what kind of structure you should be using.
It seems to me that you could achieve this by just using a function, if the code inside the loop is the same. Like this:
if($something == true)
{
foreach($array as $arr)
{
doWork($arr);
}
}
else
{
while($row = mysql_fetch_array($mysql_query))
{
doWork($row);
}
}
function doWork($arr)
{
//...
}
You cannot nest loop instructions inside a loop like this. You'll need to have two separate loops completely inside the IF statements.
if($something == true){
foreach($array as $arr){
// do work
}
} else {
while($row = mysql_fetch_array($mysql_query)){
// do work
}
}
Maybe you could look at from this viewpoint. And take note that this code uses mysql_fetch_assoc() instead of mysql_fetch_array(). Try both functions and look at the resulting rows with var_dump(). You will see that mysql_fetch_array() has twice as much data. You may want that, but probably not.
if ($something !== true)
{
$array = array();
while($row = mysql_fetch_assoc($mysql_query_result_resource))
{
$array[] = $row;
}
}
foreach($array as $arr)
{
/* PROCESS */
}

Multi-dimensional array search to preserve parent

TL;DR
I have this data: var_export and print_r.
And I need to narrow it down to: http://pastebin.com/EqwgpgAP ($data['Stock Information:'][0][0]);
How would one achieve it? (dynamically)
I'm working with vTiger 5.4.0 CRM and am looking to implement a function that would return a particular field information based on search criteria.
Well, vTiger is pretty weakly written system, looks and feels old, everything comes out from hundreds of tables with multiple joins (that's actually not that bad) etc., but job is job.
The need arose from getting usageunit picklist from Products module, Stock Information block.
Since there is no such function as getField();, I am looking forward to filter it out from Blocks, that is actually gathering the information about fields also.
getBlocks(); then calls something close to getFields();, that again something close to getValues(); and so on.
So...
$focus = new $currentModule(); // Products
$displayView = getView($focus->mode);
$productsBlocks = getBlocks($currentModule, $displayView, $focus->mode, $focus->column_fields); // in theory, $focus->column_fields should/could be narrowed down to my specific field, but vTiger doesn't work that way
echo "<pre>"; print_r($productsBlocks); echo "</pre>"; // = http://pastebin.com/3iTDUUgw (huge dump)
As you can see, the array under the key [Stock Information:], that actually comes out from translations (yada, yada...), under [0][0] contains information for usageunit.
Now, I was trying to array_filter(); the data out from there, but only thing I've managed to get is $productsBlocks stripped down to only contain [Stock Information:] with all the data:
$getUsageUnit = function($value) use (&$getUsageUnit) {
if(is_array($value)) return array_filter($value, $getUsageUnit);
if($value == 'usageunit') return true;
};
$productsUsageUnit = array_filter($productsBlocks, $getUsageUnit);
echo "<pre>"; print_r($productsUsageUnit); echo "</pre>"; // = http://pastebin.com/LU6VRC4h (not that huge of a dump)
And, the result I'm looking forward to is http://pastebin.com/EqwgpgAP, that I've manually got by print_r($productsUsageUnit['Stock Information:'][0][0]);.
How do I achieve this? (dynamically...)
function helper($data, $query) {
$result = array();
$search = function ($data, &$stack) use(&$search, $query) {
foreach ($data as $entry) {
if (is_array($entry) && $search($entry, $stack) || $entry === $query) {
$stack[] = $entry;
return true;
}
}
return false;
};
foreach ($data as $sub) {
$parentStack = array();
if ($search($sub, $parentStack)) {
$result[] = $parentStack[sizeof($parentStack) - 2];
}
}
return $result;
}
$node = helper($data, 'usageunit');
print_r($node);

convert array to object in php

In php I am converting posted data from a form to objects like this:
<?php
...some code...
$post = new stdClass;
foreach ($_POST as $key => $val)
$post->$key = trim(strip_tags($_POST[$key]));
?>
Then in my page I just echo posted data like this :
<?php echo $post->Name; ?>
<?php echo $post->Address; ?>
etc...
This works fine but I have multiple checkboxes that are part of a group and I echo the results of that, like this:
<?php
$colors = $_POST['color_type'];
if(empty($colors))
{
echo("No color Type Selected.");
}
else
{
$N = count($colors);
for($i=0; $i < $N; $i++)
{
echo($colors[$i] . ", ");
}
}
?>
That works when I am just using array, but how do I write this as object syntax?
using your code
function array_to_object($arr) {
$post = new stdClass;
foreach ($arr as $key => $val) {
if(is_array($val)) {
$post->$key = post_object($val);
}else{
$post->$key = trim(strip_tags($arr[$key]));
}
}
return $post;
}
$post = array_to_object($_POST);
or more complex solution
function arrayToObject($array) {
if(!is_array($array)) {
return $array;
}
$object = new stdClass();
if (is_array($array) && count($array) > 0) {
foreach ($array as $name=>$value) {
$name = strtolower(trim($name));
if (!empty($name)) {
$object->$name = arrayToObject($value);
}
}
return $object;
}
else {
return FALSE;
}
}
from http://www.richardcastera.com/blog/php-convert-array-to-object-with-stdclass
why would you want that? What's wrong with an array?
Use Object Oriented Programming, which might be what you are looking for. Treat it as an object, by making a class called Color and doing $colors[$i] = new Color();
This way you can do whatever you want with it, and add functions to it.
Pretty simple -- when you attach the color_type key to your object, it'll become an array that's a property of your object. This is most likely what you want: you probably won't want to turn that array into its own stdClass-based object, because then you won't be able to iterate through all the values (as easily). Here's a snippet:
<?php
// putting in both of these checks prevents you from throwing an E_WARNING
// for a non-existent property. E_WARNINGs aren't dangerous, but it makes
// your error messages cleaner when you don't have to wade through a bunch
// of E_WARNINGS.
if (!isset($post->color_type) || empty($post->color_type)) {
echo 'No colour type selected.'; // apologies for the Canadian spelling!
} else {
// this loop does exactly the same thing as your loop, but it makes it a
// bit more succinct -- you don't have to store the count of array values
// in $N. Bit of syntax that speeds things up!
foreach ($post->color_type as $thisColor) {
echo $thisColor;
}
}
?>
Hope this helps! Of course, in a real-life setting, you'll want to do all sorts of data validation and cleaning -- for instance, you'll want to check that the browser actually passed an array of values for $_POST['color_type'], and you'll want to clean the output in case someone is trying to inject an exploit into your page (by going echo htmlspecialchars($thisColor); -- this turns all characters like < and > into HTML entities so they can't insert JavaScript code).

Output a result of an SQL query to a PHP array

I'm new to OOP in PHP, is that to seems correct ?
class whatever {
Function Maths() {
$this->sql->query($requete);
$i = 0;
while($val = mysql_fetch_array($this)) {
$tab[i][average] = $val['average'];
$tab[i][randomData] = $val['sum'];
$i=$i+1;
}
return $tab;
}
I want to access the data contained in the array
$foo = new whatever();
$foo->Maths();
for ($i, $i <= endOfTheArray; i++) {
echo Maths->tab[i][average];
echo Maths->tab[i][randomData];
}
Thank you ;)
EDIT: i want to output the result of the SQL query as an array, so i can access it from outside the class
In the interest of helping you out, here are some modifications. Please hear this, though: a lot of this might not make sense without a good background in PHP or OOP in general. You should look at #webbiedave's link.
class whatever {
static function maths() {
$tabs = array();
$results = $this->sql->query($requete);
while($val = mysql_fetch_array($this)) {
$tabs = $val;
}
return $tabs;
}
This fixes syntax errors and logic errors (for instance, the creation of the $results variable to hold the SQL query run).
I made the maths method static, since there's really no need to instantiate a whatever() object with this current example.
Here are some modifications to how this would be used:
$results = whatever::maths();
foreacho ($results as $result) {
echo $result['average'];
echo $result['randomData'];
}
Since maths() returns something, you need to store that in a variable; simply calling it, as you did previously, doesn't do anything.
That convoluted for loop can be replaced with a foreach loop.
Please check out PHP OOP basics:
http://www.php.net/manual/en/language.oop5.basic.php
Edit: Thanks for cleaning up the code. Try something along the lines of:
$tabs = array();
while($val = mysql_fetch_assoc($result)) {
$tabs[] = $val;
}
And:
$foo = new whatever();
$tabs = $foo->Maths();
for ($tabs as $tab) {
echo $tab['average'];
echo $tab['randomData'];
}
http://www.php.net/manual/en/language.oop5.basic.php

Categories