PHP if statment on array length not working - php

here is my code :
elseif (is_dir($dir)) {
$scanning = scandir($dir);
$okdir;
// $response["scan"] = $scanning;
foreach ($scanning as $key=> $value) {
$splitscan = explode("_",$scanning[$key]);
if ($splitscan[0] == $searchvalue ){
$okdir[] = $scanning[$key];
if (count($okdir)>1){
$response["okdir"] = $okdir;
$response["result"] = "more";
}
else {
$okdir = $okdir[0];
}
}
}
when the function goes on the else statment i get no problem, but when the conditions need to verify the if statment if(count($okdir>1)) i get PHP internal error. What does it mean? That the if statment is never true? What i'm doing wrong?
Thank you for any help provided
Here is the error log answer:
PHP Fatal error: Uncaught Error: [] operator not supported for strings
Here is the whole function:
private function pdf(){
$response;
$dir = "../Pdf/";
$searchvalue = $this->params["utentericercato"];
if (!isset($_COOKIE["idutente"])){
$response["result"] = "nosession";
$utente->setUteLogged(false);
}
// Open a known directory, and proceed to read its contents
elseif (is_dir($dir)) {
$scanning = scandir($dir);
$okdir = array();
// $response["scan"] = $scanning;
foreach ($scanning as $key=> $value) {
$splitscan = explode("_",$scanning[$key]);
if ($splitscan[0] == $searchvalue ){
$okdir[] = $scanning[$key];
if (count($okdir)>1){
$response["okdir"] = $okdir;
$response["result"] = "more";
}
else {
$okdir = $okdir[0];
}
}
}
if (empty($okdir)){
$response["result"]= "noutente";
}
else {
$newdir = $dir.$okdir;
$nomeutente = preg_replace("/[^a-zA-Z\s]/", "", $okdir);
$response["dir"] = $newdir;
$response["nomeutente"] = $nomeutente;
if (is_dir($newdir)){
$dh = array_diff(scandir($newdir),array(".",".."));
$arr = is_array($dh);
$x = 0;
while($x < sizeof($dh)){
foreach($dh as $key=>$value){
if ($key[$value] != "." && $key[$value] != ".."){
$response["files"][$key] = $value;
$response["result"] = "success";
}
$x = $x + 1;
}
}
}
}
}
else {
$response["result"] = "nodirectory";
}
Responder::giveResponse($response);
}

Your first iteration sets the variable as a string. Any subsequent iteration will attempt to "push" data into the string like it is an array.
Demo: https://3v4l.org/GOdgs
$scanning[0] = "b";
$okdir = "a"; // just add [] after $okdir
$okdir[] = $scanning[0];
var_export($okdir);
I suppose I recommend that you just remove:
else {
$okdir = $okdir[0];
}
It only causes trouble.
And...
if (count($okdir)>1){
$response["okdir"] = $okdir;
$response["result"] = "more";
}
Should be positioned after your loop so that it is executed only once.
If this were my project, I'd be doing something like chdir($dir); then glob("{$searchvalue}_*") <-- grab and filter in the same step.

I did not test it yet, however, this much cleaner approach should work. At least it should give you an idea how to do the task in a structured way.
private function pdf()
{
$response = [];
$dir = "../Pdf/";
$searchvalue = $this->params["utentericercato"];
if (is_dir($dir))
{
chdir($dir);
$okdir = glob("{$searchvalue}_*", GLOB_ONLYDIR);
switch (count($okdir))
{
case 0:
$response['result'] = 'noutente';
break;
case 1:
$nomeutente = preg_replace("/[^a-z\s]/i", "", $okdir[0]);
$response["dir"] = $dir . $okdir[0];
$response["nomeutente"] = $nomeutente;
chdir($okdir[0]);
$response["files"] = glob('*');
if(!empty($response["files"]))
{
$response["result"] = "success";
}
break;
default:
$response["okdir"] = $okdir; // or $okdir[0] if you do not want an array but the first item
$response["result"] = "more";
}
}
else
{
$response["result"] = "nodirectory";
}
Responder::giveResponse($response);
}

Here is the error log answer: PHP Fatal error: Uncaught Error: [] operator not supported for strings
To fix the error above, define $okdir as array.
Line no 3 should be changed from $okdir; to $okdir = array();

I've found the solution, old code not working:
elseif (is_dir($dir)) {
$scanning = scandir($dir);
$okdir = array();
// $response["scan"] = $scanning;
foreach ($scanning as $key=> $value) {
$splitscan = explode("_",$scanning[$key]);
if ($splitscan[0] == $searchvalue ){
$okdir[] = $scanning[$key];
if (count($okdir)>1){
$response["okdir"] = $okdir;
$response["result"] = "more";
}
else {
$okdir = $okdir[0];
}
}
}
if (empty($okdir)){
$response["result"]= "noutente";
}
new working code :
elseif (is_dir($dir)) {
$scanning = scandir($dir);
$okdir = array();
// $response["scan"] = $scanning;
foreach ($scanning as $key=> $value) {
$splitscan = explode("_",$scanning[$key]);
if ($splitscan[0] == $searchvalue ){
$okdir[] = $scanning[$key];
}
}
if (count($okdir)>1){
$response["okdir"] = $okdir;
$response["result"] = "more";
Responder::giveResponse($response);
exit;
}
if (empty($okdir)){
$response["result"]= "noutente";
}

Related

Excel file created from box/spout library is not editable in microsoft excel

I just recently implemented box/spout library replacing the phpspreadsheet library in favour of memory efficiency.
I am also able to produce the excel file using it.
But after opening the excel file using ms office 2019, I cannot edit the cells at all, it just seems all shown read-only.
But if I use phpspreadsheet to generate the same thing, I can edit the file.
Do any of you folks know anything that I am missing out here.
Following is my implementation of box/spout
use Box\Spout\Common\Type;
use Box\Spout\Writer\Common\Creator\Style\StyleBuilder;
use Box\Spout\Writer\Common\Creator\WriterEntityFactory;
use PhpOffice\PhpSpreadsheet\Shared\Date;
function exprot_table($xmlObjectArray, $rows)
{
error_reporting(E_ALL);
$head = (array) $rows[0];
$headArray = array_keys($head);
$writer = WriterEntityFactory::createWriter(Type::XLSX);
$writer->openToBrowser("demoexcel.xlsx");
$rowFromValues = WriterEntityFactory::createRowFromArray($headArray);
$writer->addRow($rowFromValues);
$excelRows = array();
foreach ($rows as $key => $row) {
$row = (array) $row;
$cells = array();
foreach ($headArray as $keyc => $column) {
$fieldType = $xmlObjectArray[$column]['type'];
$col_name = $this->get_col_name($keyc);
// set date formate
if ($fieldType == "datetime") {
if (! empty($row[$column])) {
// Get server time zone offset in seconds and add or subtract from main value
$timeZoneOffset = date('Z', $row[$column]);
$date = $row[$column] + $timeZoneOffset;
$date = Date::PHPToExcel(trim($date));
$cellstyle = (new StyleBuilder())->setFormat('dd mmm yyyy')->build();
$cells[] = WriterEntityFactory::createCell($date, $cellstyle);
} else {
$cells[] = WriterEntityFactory::createCell('');
}
} elseif ($fieldType == "money") {
if (strlen($row[$column]) > 0) {
$cellstyle = (new StyleBuilder())->setFormat('#,##0.00;[Red]#,##0.00')->build();
$cells[] = WriterEntityFactory::createCell($row[$column], $cellstyle);
} else {
$cells[] = WriterEntityFactory::createCell('');
}
}elseif ($fieldType == "number") {
if (strlen($row[$column]) > 0) {
$cellstyle = (new StyleBuilder())->setFormat('#,##')->build();
$cells[] = WriterEntityFactory::createCell($row[$column], $cellstyle);
} else {
$cells[] = WriterEntityFactory::createCell('');
}
} elseif ($fieldType == "image") {
$value = $row[$column];
if (! empty($value)) {
$imageFolder = $this->config->item('img_upload_path');
$subDirectory = (string) $xmlObjectArray[$column]['sub_directory'];
if (isset($subDirectory) and ! empty($subDirectory)) {
$imageFolder .= $subDirectory . "/";
}
$filePath = $imageFolder . $value;
if (stripos($value, 'https://') !== false || stripos($value, 'http://') !== false) {
$cells[] = WriterEntityFactory::createCell('=HYPERLINK("'. $value .'","'. $value .'")');
} else {
$cells[] = WriterEntityFactory::createCell($value);
}
}
} elseif ($fieldType == "file") {
$value = $row[$column];
$imageFolder = $this->config->item('img_upload_path');
if (! empty($value)) {
$value = CDN_URL . $imageFolder . $value;
}
$cells[] = WriterEntityFactory::createCell($value);
} else {
$cells[] = WriterEntityFactory::createCell($row[$column]);
}
}
$excelRows[] = WriterEntityFactory::createRow($cells);
}
$writer->addRows($excelRows);
ob_clean();
$writer->close();
exit();
}

How to correctly write a foreach for $clientList in TS3AntiVPN application?

I download a TS3AntiVPN but it shoes an error. I use a Linux Server running Debian 9 Plesk installed.
PHP Warning: Invalid argument supplied for foreach() in
/var/www/vhosts/suspectgaming.de/tsweb.suspectgaming.de/antivpn/bot.php
on line 29
How do I solve this problem?
<?php
require("ts3admin.class.php");
$ignore_groups = array('1',); // now supports one input and array input
$msg_kick = "VPN";
$login_query = "serveradmin";
$pass_query = "";
$adres_ip = "94.249.254.216";
$query_port = "10011";
$port_ts = "9987";
$nom_bot = "AntiVPN";
$ts = new ts3Admin($adres_ip, $query_port);
if(!$ts->getElement('success', $ts->connect())) {
die("Anti-Proxy");
}
$ts->login($login_query, $pass_query);
$ts->selectServer($port_ts);
$ts->setName($nom_bot);
while(true) {
sleep(1);
$clientList = $ts->clientList("-ip -groups");
foreach($clientList['data'] as $val) {
$groups = explode(",", $val['client_servergroups'] );
if(is_array($ignore_groups)){
foreach($ignore_groups as $ig){
if(in_array($ig, $groups) || ($val['client_type'] == 1)) {
continue;
}
}
}else{
if(in_array($ignore_groups, $groups) || ($val['client_type'] == 1)) {
continue;
}
}
$file = file_get_contents('https://api.xdefcon.com/proxy/check/?ip='.$val['connection_client_ip'].'');
$file = json_decode($file, true);
if($file['message'] == "Proxy detected.") {
$ts->clientKick($val['clid'], "server", $msg_kick);
}
}
}
?>
You might be missing data in your first array. You may add an if statement to check if there is data in your $clientList['data'] var:
if (is_array($clientList['data'])) {
}
Or you might also check if sizeof(); of your array is larger than a number, you may desire.
if (is_array($clientList['data']) && sizeof($clientList['data']) > 0) {
}
Code
require "ts3admin.class.php";
$ignore_groups = array('1'); // now supports one input and array input
$msg_kick = "VPN";
$login_query = "serveradmin";
$pass_query = "";
$adres_ip = "94.249.254.216";
$query_port = "10011";
$port_ts = "9987";
$nom_bot = "AntiVPN";
$ts = new ts3Admin($adres_ip, $query_port);
if (!$ts->getElement('success', $ts->connect())) {
die("Anti-Proxy");
}
$ts->login($login_query, $pass_query);
$ts->selectServer($port_ts);
$ts->setName($nom_bot);
while (true) {
sleep(1);
$clientList = $ts->clientList("-ip -groups");
if (is_array($clientList['data']) && sizeof($clientList['data']) > 0) {
foreach ($clientList['data'] as $val) {
$groups = explode(",", $val['client_servergroups']);
if (is_array($ignore_groups)) {
foreach ($ignore_groups as $ig) {
if (in_array($ig, $groups) || ($val['client_type'] == 1)) {
continue;
}
}
} else {
if (in_array($ignore_groups, $groups) || ($val['client_type'] == 1)) {
continue;
}
}
$file = file_get_contents('https://api.xdefcon.com/proxy/check/?ip=' . $val['connection_client_ip'] . '');
$file = json_decode($file, true);
if ($file['message'] == "Proxy detected.") {
$ts->clientKick($val['clid'], "server", $msg_kick);
}
}
} else {
echo "There might be no data in Client List";
}
}

How to repeat the same action for diffrent variables

<!-- language: php -->
<?php
// test variables
$l1 = "http://youtube.com/channel/";
$l2 = "http://youtube.com/channel/";
$l3 = "http://youtube.com/channel/";
$l4 = "http://youtube.com/channel/";
$fl = "http://youtube.com/channel/";
//set error false as default
$error = "false";
//check if variables are ready for use, if they are, add them to `$l` array
//I do each check as a seperate line, as it looks cleaner than 1 long if statement.
$l = [];
if(!empty($l1)) $l[] = $l1;
if(!empty($l2)) $l[] = $l2;
if(!empty($l3)) $l[] = $l3;
if(!empty($l4)) $l[] = $l4;
if(!empty($fl)) $l[] = $fl;
foreach($l as $key => $value) {
//1 line ternary is cleaner than if/else statetmnt
$errorKey = $key < 9? "0{$key}" : $key;
//each row by default has no error
$hasError = 0;
//check if this a valid url
if(!preg_match('|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i', $value)) {
$error = "true";
$hasError = 1;
}
if($hasError) {
//store error in array, to loop through later
$errors[] = $errorKey;
}
}
$search = '?sub_confirmation=1';
$searchUrl = "youtube.com/channel";
if (strpos($l, $searchUrl) !== false && strpos($l, $search) === false) {
$l = $value."".$search;
}
if($error == "false") {
echo $l1;
echo $l2;
echo $l3;
echo $l4;
echo $fl;
}
// deliver the error message
//Check if $error has been set to true at any point
if($error == "true") {
//loop through error array, echo error message if $errorNumber matches.
//at this point we KNOW there was an error at some point, no need to use a switch really
foreach($errors as $errorNumber) {
echo "Something went wrong here $errorNumber :o";
}
}
?>
Hello, my problem is at the end of the code where the strpos function is, so basically I want to check every url, once if it contains a certain url, and then add something to the end if it is so. But I don't want to repeat an if statement 4 times($fl variable doesn't has to be checked), I am quite new in all that so I hope somebody can help me, I tought about a switch statement but I guess there is a better way. And if I put it in the foreach aboth, it doesn't applies on the certain variables, only on the value variable.
You can assign $value by reference using this foreach header (notice the & in front of $value):
foreach($l as $key => &$value) {
By doing this every change you do to $value will also be done to the corresponding value in the $l array.
Then at the end of the foreach loop you put this code:
if (strpos($value, $searchUrl) !== false && strpos($value, $search) === false) {
$value .= $search;
}
So your final foreach loop should look like this:
foreach($l as $key => &$value) {
//1 line ternary is cleaner than if/else statetmnt
$errorKey = $key < 9? "0{$key}" : $key;
//each row by default has no error
$hasError = 0;
//check if this a valid url
if(!preg_match('|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i', $value)) {
$error = "true";
$hasError = 1;
}
if($hasError) {
//store error in array, to loop through later
$errors[] = $errorKey;
}
$search = '?sub_confirmation=1';
$searchUrl = "youtube.com/channel";
if (strpos($value, $searchUrl) !== false && strpos($value, $search) === false) {
$value .= $search;
}
}
You can read more about using references in foreach loops here: PHP: foreach
Edit:
To apply the changes not only to the elements of the $l array, but also to the original variables $l1, $l2 and so on, you should assign the elements to your array as references too:
$l = [];
if(!empty($l1)) $l[] = &$l1;
if(!empty($l2)) $l[] = &$l2;
if(!empty($l3)) $l[] = &$l3;
if(!empty($l4)) $l[] = &$l4;
if(!empty($fl)) $l[] = &$fl;
Personally, I think this is a good candidate for moving to a class. To be honest I'm not 100% sure what you are doing but will try to convert your code to a class.
class L {
public $raw = null;
public $modified = null;
public $error = false;
// create the class
public function __construct($data=null) {
$this->raw = $data;
// Check the raw passed in data
if ($data) {
$this->isUrl();
}
// If there was no error, check the data
if (! $this->error) {
$this->search();
}
}
// Do something ?
public function debug() {
echo '<pre>';
var_dump($this);
echo '</pre>';
}
public function getData() {
return ($this->modified) ? : $this->raw;
}
private function isUrl() {
$this->error = (! preg_match('|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i', $this->raw));
}
// Should a failed search also be an error?
private function search() {
if ($this->raw) {
if ( (strpos($this->raw, "youtube.com/channel") !== false) &&
(strpos($this->raw, "?sub_confirmation=1") === false) ) {
$this->modified = $this->raw ."?sub_confirmation=1";
}
}
}
}
// Test data
$testList[] = "test fail";
$testList[] = "https://youtube.com/searchFail";
$testList[] = "https://youtube.com/channel/success";
$testList[] = "https://youtube.com/channel/confirmed?sub_confirmation=1";
// Testing code
foreach($testList as $key=>$val) {
$l[] = new L($val);
}
foreach($l as $key=>$val) {
// Check for an error
if ($val->error) {
$val->debug();
} else {
echo '<pre>'.$val->getData().'</pre>';
}
}
And the output would be:
object(L)#1 (3) {
["raw"]=>
string(9) "test fail"
["modified"]=>
NULL
["error"]=>
bool(true)
}
https://youtube.com/searchFail
https://youtube.com/channel/success?sub_confirmation=1
https://youtube.com/channel/confirmed?sub_confirmation=1

How to save the changes made with a script

With this script, change the order of the lines in a text file, but I'd like to save the file as a new file. How can I do that?
<?php
$file = "menu2.txt";
$righe = file($file);
$numrighe = count($righe);
$portieri = array();
$difensori = array();
$aladestra = array();
$alasinistra = array();
$attaccante = array();
for($i=0; $i < $numrighe;$i++) {
$riga = $righe[$i];
list($giocatore, $ruolo) = preg_split("[>]", $riga);
if(strcmp($ruolo,"Portiere")) { array_push($portieri, $giocatore); }
else if(strcmp($ruolo,"Difensore")) { array_push($difensori, $giocatore); }
else if(strcmp($ruolo,"Ala destra")) { array_push($aladestra, $giocatore); }
else if(strcmp($ruolo,"Ala sinistra")) { array_push($alasinistra, $giocatore); }
else if(strcmp($ruolo,"Attaccante")) { array_push($attaccante, $giocatore); }
}
?>
Excuse me but probably because of google translator or because they are prevented, but you probably will not understand it, I did it:
<?php
$file = "menu2.txt";
$righe = file($file);
$numrighe = count($righe);
$portieri = array();
$difensori = array();
$aladestra = array();
$alasinistra = array();
$attaccante = array();
for($i=0; $i < $numrighe;$i++) {
$riga = $righe[$i];
list($giocatore, $ruolo) = preg_split("[>]", $riga);
if(strcmp($ruolo,"Portiere")) { array_push($portieri, $giocatore); }
else if(strcmp($ruolo,"Difensore")) { array_push($difensori, $giocatore); }
else if(strcmp($ruolo,"Ala destra")) { array_push($aladestra, $giocatore); }
else if(strcmp($ruolo,"Ala sinistra")) { array_push($alasinistra, $giocatore); }
else if(strcmp($ruolo,"Attaccante")) { array_push($attaccante, $giocatore); }
}
// open your new file
$newFile = fopen('newmenu2.txt', 'w');
// write to your file using $newFile file handler,
// with the imploded data you want to write into your file
fwrite($newFile, implode("\n", $data));
// close your file handler
fclose($newFile);
?>
Notice: Undefined variable: data on line 29
Warning: implode(): Invalid arguments passed on line 29

PHP FTP recursive directory listing

I'm trying to make a recursive function to get all the directories and sub directories from my ftp server in an array.
I tried a lot of functions I've found on the web. The one that works best for me is this one:
public function getAllSubDirFiles() {
$dir = array(".");
$a = count($dir);
$i = 0;
$depth = 20;
$b = 0;
while (($a != $b) && ($i < $depth)) {
$i++;
$a = count($dir);
foreach ($dir as $d) {
$ftp_dir = $d . "/";
$newdir = ftp_nlist($this->connectionId, $ftp_dir);
foreach ($newdir as $key => $x) {
if ((strpos($x, ".")) || (strpos($x, ".") === 0)) {
unset($newdir[$key]);
} elseif (!in_array($x, $dir)) {
$dir[] = $x;
}
}
}
$b = count($dir);
}
return $dir ;
}
The problem with this function is it wont allow the directory to have a "." in it's name and every file that is located in the root directory will be considered a directory as well. So I adjusted the function and got this:
public function getAllSubDirFiles($ip, $id, $pw) {
$dir = array(".");
$a = count($dir);
$i = 0;
$depth = 20;
$b =0;
while (($a != $b) && ($i < $depth)) {
$i++;
$a = count($dir);
foreach ($dir as $d) {
$ftp_dir = $d . "/";
$newdir = ftp_nlist($this->connectionId, $ftp_dir);
foreach ($newdir as $key => $x) {
if (!is_dir('ftp://'.$id.':'.$pw.'#'.$ip.'/'.$x)) {
unset($newdir[$key]);
} elseif (!in_array($x, $dir)) {
$dir[] = $x;
}
}
}
$b = count($dir);
}
return $dir ;
}
This works pretty good but and gives the result I want. but it's so slow it's unusable.
I also tried working with ftp_rawlist but it has the same drawback of being horribly slow.
public function getAllSubDirFiles() {
$dir = array(".");
$a = count($dir);
$i = 0;
$depth = 20;
$b = 0;
while (($a != $b) && ($i < $depth)) {
$i++;
$a = count($dir);
foreach ($dir as $d) {
$ftp_dir = $d . "/";
$newdir = $this->getFtp_rawlist('/' . $ftp_dir);
foreach ($newdir as $key => $x) {
$firstChar = substr($newdir[$key][0], 0, 1);
$a = 8;
while ($a < count($newdir[$key])) {
if ($a == 8) {
$fileName = $ftp_dir . '/' . $newdir[$key][$a];
} else {
$fileName = $fileName . ' ' . $newdir[$key][$a];
}
$a++;
}
if ($firstChar != 'd') {
unset($newdir[$key]);
} elseif (!in_array($fileName, $dir)) {
$dir[] = $fileName;
}
}
}
$b = count($dir);
}
return $dir;
}
public function getFtp_rawlist($dir) {
$newArr = array();
$arr = ftp_rawlist($this->connectionId, $dir);
foreach ($arr as $value) {
$stringArr = explode(" ", $value);
$newArr[] = array_values(array_filter($stringArr));
}
return $newArr;
}
I've been stuck on this problem for the last couple of days and I'am getting desperate. If any one has any suggestion please let me know
If your server supports MLSD command and you have PHP 7.2 or newer, you can use ftp_mlsd function:
function ftp_mlsd_recursive($ftp_stream, $directory)
{
$result = [];
$files = ftp_mlsd($ftp_stream, $directory);
if ($files === false)
{
die("Cannot list $directory");
}
foreach ($files as $file)
{
$name = $file["name"];
$filepath = $directory . "/" . $name;
if (($file["type"] == "cdir") || ($file["type"] == "pdir"))
{
// noop
}
else if ($file["type"] == "dir")
{
$result = array_merge($result, ftp_mlsd_recursive($ftp_stream, $filepath));
}
else
{
$result[] = $filepath;
}
}
return $result;
}
If you do not have PHP 7.2, you can try to implement the MLSD command on your own. For a start, see user comment of the ftp_rawlist command:
https://www.php.net/manual/en/function.ftp-rawlist.php#101071
If you cannot use MLSD, you will particularly have problems telling if an entry is a file or folder. While you can use the ftp_size trick, calling ftp_size for each entry can take ages.
But if you need to work against one specific FTP server only, you can use ftp_rawlist to retrieve a file listing in a platform-specific format and parse that.
The following code assumes a common *nix format.
function ftp_nlst_recursive($ftp_stream, $directory)
{
$result = [];
$lines = ftp_rawlist($ftp_stream, $directory);
if ($lines === false)
{
die("Cannot list $directory");
}
foreach ($lines as $line)
{
$tokens = preg_split("/\s+/", $line, 9);
$name = $tokens[8];
$type = $tokens[0][0];
$filepath = $directory . "/" . $name;
if ($type == 'd')
{
$result = array_merge($result, ftp_nlst_recursive($ftp_stream, $filepath));
}
else
{
$result[] = $filepath;
}
}
return $result;
}
For DOS format, see: Get directory structure from FTP using PHP.
I've build an OOP FTP Client library that's can help you on this a lot, using just this code you can retrieve a list of only the directories with addition useful information like (chmod, last modified time, size ...).
The code :
// Connection
$connection = new FtpConnection("localhost", "foo", "12345");
$connection->open();
// FtpConfig
$config = new FtpConfig($connection);
$config->setPassive(true);
$client = new FtpClient($connection);
$allFolders =
// directory, recursive, filter
$client->listDirectoryDetails('/', true, FtpClient::DIR_TYPE);
// Do whatever you want with the folders
This code a variation of Martin Prikryl one. It is slower but do not have any failures with whitespaces. Use this code only if you have any problems with the code above.
function ftp_list_files_recursive($ftp_stream, $path){
$lines = ftp_nlist($ftp_stream, $path);
$result = array();
foreach ($lines as $line) {
if (ftp_size($ftp_stream, $line) == -1) {
$result = array_merge($result, ftp_list_files_recursive($ftp_stream, $line));
}
else{
$result[] = $line;
}
}
return $result;
}

Categories