I have created one process to read information from files and save into database, everything works fine in my desenv environment, but when I have put files in my php host (production environment) the process fail when read files.
to execute my process, I have created one cron job on cpanel, whith the command bellow:
php -q /home/<hostfolder>/batch/index.php
When my process is executed by cron, the output say that don't have files. Bellow part of my code:
private $sourceFilesFolder = "/home/<host folder>/public_html/batch/arquivos";
private $destFilesFolder = "/home/<host folder>/public_html/batch/processados";
private $log;
private $trataException;
function __construct($log, $trataException) {
$this->log = $log;
$this->trataException = $trataException;
}
/**
* Read the source folder and select only files
* #return array - Array of valid files
*/
function selectFiles() {
// Save the first read of ftp folder
$listSourceFolder = scandir ( $this->sourceFilesFolder );
// Array tho save only valid files
$listFiles = array ();
// read the array with ftp content and save in listFiles only files
foreach ( $listSourceFolder as $file ) {
$verifica = $this->sourceFilesFolder . "\\" . $file;
// if is a file type, try save in listFiles array
if (($file != ".") && ($file != "..") && (!is_dir ( $verifica ))) {
// verifiy if the file exists
if (file_exists ( $verifica )) {
$this->log->gravaLog ( $file . " -> ADDED TO PROCESS" );
//verificaArquivoEmUso ( $verifica );
array_push ( $listFiles, $verifica );
} else
$this->log->gravaLog ( $file . "-> do not exist." );
} else
$this->log->gravaLog ( $file . "-> not is a file." );
}
return $listFiles;
}
In my folder I have two txt files and this appear in the $listSourceFolder variable, but when I check this files with file_exists, always return false.
First, I have put my code files in a bacth folder in /home/
In the second test, I move the files in ftp folder and put inside the bacth folder (same of my code).
In the third test, I moved all batch folder (with codes and txt files) to public_html folder.
Nothing work, always the same error, file not exists.
I tryed remove ths file_exists if, but occur erros on the next step of algoritm.
I have checked the file permissions, and all permissions are ok.
What is I can do???
You can try three things.
1 - chmod 777 (Give permission so php can read and write files)
2 - I know its practically impossible that your server has a lower version of php. Scandir only works php 5 above. So you might wanna check that.
3 - There's a module called "mod_speling", try put that on.
;)
It appears that you are using the incorrect path delimiter for *nix.
You might change your code to be the following instead:
$verifica = $this->sourceFilesFolder . "/" . $file;
Related
I currently have the function:
function deleteFileUsingID($fileID) {
$this->service->files->delete($fileID);
}
How would I have to modify it such that after deleting the file, if no files exists within that folder, it deletes the folder itself.
I believe your goal as follows.
When there are no files in the specific folder, you want to delete the folder.
In this case, you can check whether the files are in the folder using the method of "Files: list" in Drive API.
Modified script:
Please set the folder ID to $folderId = '###';.
function deleteFileUsingID($fileID) {
$this->service->files->delete($fileID);
$folderId = '###'; // Please set the folder ID.
$fileList = $this->service->files->listFiles(array("q" => "'{$folderId}' in parents"));
if (count($fileList->getFiles()) == 0) {
$this->service->files->delete($folderId);
}
}
Or, when you want to retrieve the folder ID from $fileID, you can also use the following script.
function deleteFileUsingID($fileID) {
$folderIds = $this->service->files->get($fileID, array("fields" => "parents"))->getParents();
$this->service->files->delete($fileID);
if (count($folderIds) > 0) {
$folderId = $folderIds[0];
$fileList = $this->service->files->listFiles(array("q" => "'{$folderId}' in parents"));
if (count($fileList->getFiles()) == 0) {
$this->service->files->delete($folderId);
}
}
}
In this modified script, after $this->service->files->delete($fileID); was run, it checks whether the files are in the folder using the method of "Files: list". When no files in the folder, the folder is deleted.
Note:
In this case, the folder is deleted. So please be careful this. I would like to recommend to use the sample folder for testing the script.
Reference:
Files: list
I've created a basic page where people "sign up" to upload/delete files in their own isolated folder.
The uploading/deleting of files are secure, however I would also like to allow admins to "deny" files.
The code alone works, except if anyone changes the URL to somewhere else on the server, they can "deny" any file on the system putting it at risk. I am looking to create a system function of which detects if the file they are targeting exists anywhere in the directory tree.
Here's the code that I am using of which I'd like to create a function that returns either true/false.
<?php
if(isset($_GET['deny'])) {
$tree_start = "Uploads";
$targeted_file = $_GET['deny'];
$safe_to_delete = in_directory_tree($tree_start, $targeted_file); <-- Looking for this
if( $safe_to_delete == false ) {die("This file does not exist in the directory tree");}
rename($_GET['deny'], "./Uploads/#Denied/". basename($_GET['deny']) );
}
?>
My Directory tree:
.htaccess <-- Prevent downloading of the database
admin.php <-- Problematic file browser script
index.php <-- User File management script
Users.db <-- Names and hashed passwords
Uploads:
[FILE] htaccess <-- Prevent script execution (layer 2).
[DIR] #Accepted: Notes.png, Video.mp4, etc...
[DIR] #Denied: Project.png, new_timetable.txt, etc...
[DIR] Admin: Proj1.txt, Proj1.png, etc...
[DIR] User1: Task1.txt, Task2.txt, etc...
[DIR] User2: Video1.txt, date.txt, etc...
give this code a try:
function in_directory_tree($dir,$file_to_search){
$filesList = new RecursiveDirectoryIterator("uploads");
$targetFile = "contact.php" ;
foreach(new RecursiveIteratorIterator($filesList) as $file)
{
$contents = explode("\\",$file);
if (in_array($targetFile, $contents))
return true;
}
return false;
}
This code will load the directory and start searching recursively, if it reaches the end without finding the file it will return false, otherwise it will return true.
I used RecursiveDirectoryIterator as it will help us get inside directories to list them
I have solved this problem by preventing path traversal instead of checking if the file exists in this folder. This code works for me (returns true only when a file in /uploads exists (and blocks going back using C:/, ../, etc), and returns true only when the file does exist. Here is the finished code:
<?php
// Code used for the deny button:
// <button onclick="location.href='?deny=SmilerRyan/Project.png';">Deny</button>
if(isset($_GET['deny'])) {
$userpath = $_GET['deny'];
$basepath = 'Uploads/';
$realBase = realpath($basepath);
$userpath = $basepath . $userpath;
$realUserPath = realpath($userpath);
if ($realUserPath === false || strpos($realUserPath, $realBase) !== 0) {
die("Invalid path - Possible Attack Blocked");
} else {
rename($userpath, "./Uploads/#Denied/" . basename($userpath) );
}
}
?>
i wanna try this
link : How to check using PHP FTP functionality if folder exists on server or not?
tell me if my code is right;
i cant seem to find the folder and it echoes the failed
sample ftp account is
user: admin#mywebsite.com
pass: name#pasword
ftp file root is : /home/mywebsite/public_html/admin
path folder i want to find is: public_html/admin/userfiles
i set the path ftp account path on the admin from cpanel
if(is_dir('ftp://admin#mywebsite.com:name#pasw0rd#mywebsite.com/userfiles'))
{
echo 'found';
}
else
{
echo 'failed';
}
There are some prerequisites to using 'ftp://` this way:
The PHP directive allow_url_fopen must be set to true;
The target server must support passive ftp
Assuming both of those things, your URL must be accurate. The convention is ftp://name:password#server.example.com/folder. Your URL appears to have a spurious :name# in it.
ftp://admin#mywebsite.com:name#pasw0rd#mywebsite.com/userfiles'
^^^^^^
FTP function checks if a directory exists
<?php
function ftp_is_dir( $dir ) {
global $ftpcon;
// get current directory
$original_directory = ftp_pwd( $ftpcon );
// test if you can change directory to $dir
// suppress errors in case $dir is not a file or not a directory
if ( #ftp_chdir( $ftpcon, $dir ) ) {
// If it is a directory, then change the directory back to the original directory
ftp_chdir( $ftpcon, $original_directory );
return true;
}
else {
return false;
}
}
?>
I have uploaded a lot of images from the website, and need to organize files in a better way.
Therefore, I decide to create a folder by months.
$month = date('Yd')
file_put_contents("upload/promotions/".$month."/".$image, $contents_data);
after I tried this one, I get error result.
Message: file_put_contents(upload/promotions/201211/ang232.png): failed to open stream: No such file or directory
If I tried to put only file in exist folder, it worked. However, it failed to create a new folder.
Is there a way to solve this problem?
file_put_contents() does not create the directory structure. Only the file.
You will need to add logic to your script to test if the month directory exists. If not, use mkdir() first.
if (!is_dir('upload/promotions/' . $month)) {
// dir doesn't exist, make it
mkdir('upload/promotions/' . $month);
}
file_put_contents('upload/promotions/' . $month . '/' . $image, $contents_data);
Update: mkdir() accepts a third parameter of $recursive which will create any missing directory structure. Might be useful if you need to create multiple directories.
Example with recursive and directory permissions set to 777:
mkdir('upload/promotions/' . $month, 0777, true);
modification of above answer to make it a bit more generic, (automatically detects and creates folder from arbitrary filename on system slashes)
ps previous answer is awesome
/**
* create file with content, and create folder structure if doesn't exist
* #param String $filepath
* #param String $message
*/
function forceFilePutContents ($filepath, $message){
try {
$isInFolder = preg_match("/^(.*)\/([^\/]+)$/", $filepath, $filepathMatches);
if($isInFolder) {
$folderName = $filepathMatches[1];
$fileName = $filepathMatches[2];
if (!is_dir($folderName)) {
mkdir($folderName, 0777, true);
}
}
file_put_contents($filepath, $message);
} catch (Exception $e) {
echo "ERR: error writing '$message' to '$filepath', ". $e->getMessage();
}
}
i have Been Working on the laravel Project With the Crud Generator and this Method is not Working
#aqm so i have created my own function
PHP Way
function forceFilePutContents (string $fullPathWithFileName, string $fileContents)
{
$exploded = explode(DIRECTORY_SEPARATOR,$fullPathWithFileName);
array_pop($exploded);
$directoryPathOnly = implode(DIRECTORY_SEPARATOR,$exploded);
if (!file_exists($directoryPathOnly))
{
mkdir($directoryPathOnly,0775,true);
}
file_put_contents($fullPathWithFileName, $fileContents);
}
LARAVEL WAY
Don't forget to add at top of the file
use Illuminate\Support\Facades\File;
function forceFilePutContents (string $fullPathWithFileName, string $fileContents)
{
$exploded = explode(DIRECTORY_SEPARATOR,$fullPathWithFileName);
array_pop($exploded);
$directoryPathOnly = implode(DIRECTORY_SEPARATOR,$exploded);
if (!File::exists($directoryPathOnly))
{
File::makeDirectory($directoryPathOnly,0775,true,false);
}
File::put($fullPathWithFileName,$fileContents);
}
I created an simpler answer from #Manojkiran.A and #Savageman. This function can be used as drop-in replacement for file_put_contents. It doesn't support context parameter but I think should be enough for most cases. I hope this helps some people. Happy coding! :)
function force_file_put_contents (string $pathWithFileName, mixed $data, int $flags = 0) {
$dirPathOnly = dirname($pathWithFileName);
if (!file_exists($dirPathOnly)) {
mkdir($dirPathOnly, 0775, true); // folder permission 0775
}
file_put_contents($pathWithFileName, $data, $flags);
}
Easy Laravel solution:
use Illuminate\Support\Facades\File;
// If the directory does not exist, it will be create
// Works recursively, with unlimited number of subdirectories
File::ensureDirectoryExists('my/super/directory');
// Write file content
File::put('my/super/directory/my-file.txt', 'this is file content');
I wrote a function you might like. It is called forceDir(). It basicaly checks whether the dir you want exists. If so, it does nothing. If not, it will create the directory. A reason to use this function, instead of just mkdir, is that this function can create nexted folders as well.. For example ('upload/promotions/januari/firstHalfOfTheMonth'). Just add the path to the desired dir_path.
function forceDir($dir){
if(!is_dir($dir)){
$dir_p = explode('/',$dir);
for($a = 1 ; $a <= count($dir_p) ; $a++){
#mkdir(implode('/',array_slice($dir_p,0,$a)));
}
}
}
Trying to add the ability to delete a Folder using FTP and all subfolders and files contained within that folder.
I have built a recursive function to do so, and I feel like the logic is right, but still doesnt work.
I did some testing, I am able to delete on first run if the path is just an empty folder or just a file, but can't delete if it is a folder containing one file or a folder containing one empty subfolder. So it seems to be a problem with traversing through the folder(s) and using the function to delete.
Any ideas?
function ftpDelete($directory)
{
if(empty($directory))//Validate that a directory was sent, otherwise will delete ALL files/folders
return json_encode(false);
else{
global $conn_id;
# here we attempt to delete the file/directory
if( !(#ftp_rmdir($conn_id,$directory) || #ftp_delete($conn_id,$directory)) )
{
# if the attempt to delete fails, get the file listing
$filelist = #ftp_nlist($conn_id, $directory);
# loop through the file list and recursively delete the FILE in the list
foreach($filelist as $file)
ftpDelete($file);
#if the file list is empty, delete the DIRECTORY we passed
ftpDelete($directory);
}
else
return json_encode(true);
}
};
I took some time to write my own version of a recursive delete function over ftp, this one should be fully functional (I tested it myself).
Try it out and modify it to fit your needs, if it's still not working there are other problems. Have you checked the permissions on the files you are trying to delete?
function ftp_rdel ($handle, $path) {
if (#ftp_delete ($handle, $path) === false) {
if ($children = #ftp_nlist ($handle, $path)) {
foreach ($children as $p)
ftp_rdel ($handle, $p);
}
#ftp_rmdir ($handle, $path);
}
}
Ok found my problem. Since I wasn't moving into the exact directory I was trying to delete, the path for each recursive file being called wasn't absolute:
function ftpDeleteDirectory($directory)
{
global $conn_id;
if(empty($directory))//Validate that a directory was sent, otherwise will delete ALL files/folders
return json_encode(false);
else{
# here we attempt to delete the file/directory
if( !(#ftp_rmdir($conn_id,$directory) || #ftp_delete($conn_id,$directory)) )
{
# if the attempt to delete fails, get the file listing
$filelist = #ftp_nlist($conn_id, $directory);
# loop through the file list and recursively delete the FILE in the list
foreach($filelist as $file)
{
// return json_encode($filelist);
ftpDeleteDirectory($directory.'/'.$file);/***THIS IS WHERE I MUST RESEND ABSOLUTE PATH TO FILE***/
}
#if the file list is empty, delete the DIRECTORY we passed
ftpDeleteDirectory($directory);
}
}
return json_encode(true);
};
function recursiveDelete($handle, $directory)
{ echo $handle;
# here we attempt to delete the file/directory
if( !(#ftp_rmdir($handle, $directory) || #ftp_delete($handle, $directory)) )
{
# if the attempt to delete fails, get the file listing
$filelist = #ftp_nlist($handle, $directory);
// var_dump($filelist);exit;
# loop through the file list and recursively delete the FILE in the list
foreach($filelist as $file) {
recursiveDelete($handle, $file);
}
recursiveDelete($handle, $directory);
}
}
You have to check (using ftp_chdir) for every "file" you get from ftp_nlist to check if it is a directory:
foreach($filelist as $file)
{
$inDir = #ftp_chdir($conn_id, $file);
ftpDelete($file)
if ($inDir) #ftp_cdup($conn_id);
}
This easy trick will work, because if ftp_chdir works, the current $file is actually a folder, and you've moved into it. Then you call ftpDelete recursively, to let it delete the files in that folder. Afterwards, you move back (ftp_cdup) to continue.