I'm in trouble, I am failing to understand why this error is happening.
So when I only run this code,
function getClientProject($cliente)
{
$file = fopen("Projetos.csv","r");
$ArrayCount = 0;
$bool = false;
while(! feof($file))
{
$data = fgetcsv($file);
if($data[0] != '')
{
if(substr_compare($data[0],$cliente, 0, 3) == 0)
{
if($ArrayCount > 0)
{
$total = count($OpenProject);
for($i=0;$i<$total;$i++)
{
if($OpenProject[$i] == $data[0])
$bool = true;
}
if($bool == false)
{
$OpenProject[$ArrayCount] = $data[0];
$ArrayCount++;
}
}else
{
$OpenProject[$ArrayCount] = $data[0];
$ArrayCount++;
}
}
}
}
fclose($file);
return $OpenProject;
}
It works and returns the Array. But when I call the function this way,
include_once 'CRM files/TSread.php';
$arrayC = getClientProject('SLA');
var_dump($arrayC);
No longer works and me these errors,
What am I doing wrong?
path, the file i'm using is "Projeto.php":
and my CRM files folder:
You are opening the file using a relative path. You assume that Projetos.csv is always in the same directory as the TSread.php file. Although, when including it, you seem to be in a higher directory (outside of the CRM files directory), therefor PHP can no longer find your CSV file, since it's trying to open it relative to the upper directory now.
You could pass the full path to your getClientProject method to avoid this. So, you would get something like:
$arrayC = getClientProject('SLA', __DIR__ . '/CRM files/Projectos.csv');
Obviously, you will need to change your function a little to work with this new constructor, so it should like something like this:
function getClientProject($cliente, $csv) {
$file = fopen($csv, "r");
// Followed by the rest of your function
Related
I have a number of different hosting accounts set up for clients and need to calculate the amount of storage space being used on each account, which would update regularly.
I have a database set up to record each clients storage usage.
I attempted this first using a PHP file on each account, run by a Cron Job. If run manually by myself, it would output the correct filesize and update the correct size to the database, although when run from the Cron Job, it would output 0.
I then attempted to run this file from a Cron Job from the main account but figured this wouldn't actually work as my hosting would block files from another server and I would end up with the same result as before.
I am now playing around with FTP access to each account from a Cron Job from the main account which looks something like below, the only problem is I don't know how to calculate directory size rather than single file sizes using FTP access, and don't know how to reiterate this way? Hoping somebody might be able to help here before I end up going around in circles?
I will also add the previous first attempt too.
$ftp_conn = ftp_connect($ftp_host, 21, 420) or die("Could not connect to server");
$ftp_login = ftp_login($ftp_conn, $ftp_username, 'mypassword');
$total_size = 0;
$contents = ftp_nlist($ftp_conn, ".");
// output $contents
foreach($contents as $folder){
while($search == true){
if($folder == '..' || $folder == '.'){
} else {
$file = $folder;
$res = ftp_size($ftp_conn, $file);
if ($res != -1) {
$total_size = $total_size + $res;
} else {
$total_size = $total_size;
}
}
}
}
ftp_close($ftp_conn);
This doesn't work as it doesn't calculate folder sizes and I don't know how to open the reiterate using this method?
This second script did work but would only work if opened manually, and return 0 if run by the cron job.
class Directory_Calculator {
function calculate_whole_directory($directory)
{
if ($handle = opendir($directory))
{
$size = 0;
$folders = 0;
$files = 0;
while (false !== ($file = readdir($handle)))
{
if ($file != "." && $file != "..")
{
if(is_dir($directory.$file))
{
$array = $this->calculate_whole_directory($directory.$file.'/');
$size += $array['size'];
$files += $array['files'];
$folders += $array['folders'];
}
else
{
$size += filesize($directory.$file);
$files++;
}
}
}
closedir($handle);
}
$folders++;
return array('size' => $size, 'files' => $files, 'folders' => $folders);
}
}
/* Path to Directory - IMPORTANT: with '/' at the end */
$directory = '../public_html/';
// return an array with: size, total files & folders
$array = $directory_size->size($directory);
$size_of_site = $array['size'];
echo $size_of_site;
Please bare in mind that I am currently testing and none of the MySQLi or PHP scripts are secure yet.
If your server supports MLSD command and you have PHP 7.2 or newer, you can use ftp_mlsd function:
function calculate_whole_directory($ftp_conn, $directory)
{
$files = ftp_mlsd($ftp_conn, $directory) or die("Cannot list $directory");
$result = 0;
foreach ($files as $file)
{
if (($file["type"] == "cdir") || ($file["type"] == "pdir"))
{
$size = 0;
}
else if ($file["type"] == "dir")
{
$size = calculate_whole_directory($ftp_conn, $directory."/".$file["name"]);
}
else
{
$size = intval($file["size"]);
}
$result += $size;
}
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, as you do, 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 calculate_whole_directory($ftp_conn, $directory)
{
$lines = ftp_rawlist($ftp_conn, $directory) or die("Cannot list $directory");
$result = 0;
foreach ($lines as $line)
{
$tokens = preg_split("/\s+/", $line, 9);
$name = $tokens[8];
if ($tokens[0][0] === 'd')
{
$size = calculate_whole_directory($ftp_conn, "$directory/$name");
}
else
{
$size = intval($tokens[4]);
}
$result += $size;
}
return $result;
}
Based on PHP FTP recursive directory listing.
Regarding cron: I'd guess that the cron does not start your script with a correct working directory, so you calculate a size of a non-existing directory.
Use an absolute path here:
$directory = '../public_html/';
Though you better add some error checking so that you can see yourself what goes wrong.
I used splfileobject to open the file in PHP. File is in the same directory below code is work fine. If file is another directory and is shows error like Cannot use SplFileObject with directories
$file = new SplFileObject("files/".$file_name);
$row = 1;
while (!$file->eof()) {
$data[$row] = $file->fgetcsv();
$row++;
}
If you just want to skip directories, then is_dir() will allow you to check the type and skip it...
if ( is_dir("files/".$file_name ) == false ) {
$file = new SplFileObject("files/".$file_name);
$row = 1;
while (!$file->eof()) {
$data[$row] = $file->fgetcsv();
$row++;
}
}
I have pdf files which are report cards of students.The report card names format is <student full name(which can have spaces)><space><studentID>.I need to download files.For this I have used the following code.
if(file_exists($folder_path.'/') && is_dir(folder_path)) {
$report_files = glob(folder_path.'/*'.'_*\.pdf' );
if(count($report_files)>0)
{
$result_data = '';
$result_data = rename_filenamespaces($report_files);
var_dump($result_data);//this shows the edited filename
foreach ($result_data as $file) {
if (strpos($file,$_GET['StudentID']) !== false) {
//code for showing the pdf docs to download
}
}
}
}
//function for renaming if filename has spaces
function rename_filenamespaces($location)
{
$new_location = $location;
foreach ($location as $file) {
//check file has spaces and filename has studentID
if((strpos($file," ")!==false)&& (strpos($file,$_GET['StudentID']) !== false))
{
$new_filename = str_replace(" ","-",$file);
rename($file,$new_filename);
$new_location = $new_filename;
}
}
return $new_location;
}
The variable $result_data gives me the filename without spaces,but the for each loop is showing Warning:Invalid argument supplied for foreach(). But the filename is changed in the server directory immediately after running the function. This warning shows only for first time. I am unable to solve this.
$new_location = $new_filename;
$new_location is a array
$new_filename is a string
You have to use $new_location[$index]
or try
foreach ($new_location as &$file) {
...
...
$file = $new_filename;
I`m trying to create a function that reads a directory and returns all file's working directories in an array, but it is not working. I don`t know why the code doesn`t work, can you help me?
$postsDirectory = "../posts/";
function listFiles() {
$results = array();
$handler = opendir($postsDirectory);
while ($file = readdir($handler)) {
if ($file != "." && $file != "..") {
$results[] = getcwd($file);
}
}
closedir($handler);
return $results;
}
getcwd() returns the working directory for the script that is being executed. It doesn't take any parameters, and it has nothing to do with other files on the file system (nor does the idea of a "working directory" make sense for an arbitrary file). I assume that what you actually want is a list of all directories within a given directory.
I would use a RecursiveDirectoryIterator for this:
$it = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($postsDirectory),
FilesystemIterator::SKIP_DOTS
);
$results = array();
while($it->valid()) {
if($it->isDir()) {
$results[] = $it->getSubPath();
}
$it->next();
}
I am connecting to another server via php's ftp connect.
However I need to be able to extract all html files from it's web root which is causing me a bit of a headache...
I found this post Recursive File Search (PHP) which talks about using RecursiveDirectoryIterator function however this is for a directory on the same server as the php script its self.
I've had a go with writing my own function but not sure I've got it right... assuming that the original path sent to the method is the doc root of the server:
public function ftp_dir_loop($path){
$ftpContents = ftp_nlist($this->ftp_connection, $path);
//loop through the ftpContents
for($i=0 ; $i < count($ftpContents) ; ++$i)
{
$path_parts = pathinfo($ftpContents[$i]);
if( in_array($path_parts['extension'], $this->accepted_file_types ){
//call the cms finder on this file
$this->html_file_paths[] = $path.'/'.$ftpContents[$i];
} elseif(empty( $path_parts['extension'] )) {
//run the directory method
$this->ftp_dir_loop( $path.'/'.$ftpContents[$i] );
}
}
}
}
Has anyone seen a premade class to do something like this?
You can try
public function ftp_dir_loop($path) {
$ftpContents = ftp_nlist($this->ftp_connection, $path);
foreach ( $ftpContents as $file ) {
if (strpos($file, '.') === false) {
$this->ftp_dir_loop($this->ftp_connection, $file);
}
if (in_array(pathinfo($file, PATHINFO_EXTENSION), $this->accepted_file_types)) {
$this->html_file_paths[$path][] = substr($file, strlen($path) + 1);
}
}
}