I'm currently using two functions to delete from each folder after 1 minute but as they basically do the same thing (just different folders called). I was wondering if they could be merged into one?
function DeleteFromFolder1() {
$captchaFolder = 'folder1/';
$fileTypes = '*.jpg';
$expire_time = 1;
foreach(glob($captchaFolder . $fileTypes) as $Filename) {
$FileCreationTime = filectime($Filename);
$FileAge = time() - $FileCreationTime;
if($FileAge > ($expire_time * 60))
{
unlink($Filename);
}
}
}
function DeleteFromFolder2() {
$captchaFolder = 'folder2/';
$fileTypes = '*.jpg';
$expire_time = 1;
foreach(glob($captchaFolder . $fileTypes) as $Filename) {
$FileCreationTime = filectime($Filename);
$FileAge = time() - $FileCreationTime;
if($FileAge > ($expire_time * 60))
{
to ($Filename);
}
}
}
Pass the folder name as an argument.
function DeleteFromFolder($captchaFolder) {
$fileTypes = '*.jpg';
$expire_time = 1;
foreach(glob($captchaFolder . $fileTypes) as $Filename) {
$FileCreationTime = filectime($Filename);
$FileAge = time() - $FileCreationTime;
if($FileAge > ($expire_time * 60))
{
unlink($Filename);
}
}
}
Thanks for your answers everyone but I have now sorted it by adding:
unlink(path/to/temp/image.jpg);
to my results page which deletes the uploaded image once the thumb is created and removed the function associated with it.
Once again thanks for your answers :)
function DeleteFromFolder($captchaFolder) {
$fileTypes = '*.jpg';
// and so on
}
If you like, you can add two helper functions
function DeleteFromFolder1() { return DeleteFromFolder('folder1/'); }
function DeleteFromFolder2() { return DeleteFromFolder('folder2/'); }
To try to do this without editing your structure you can pass a variable into your main function. You can do something like this
function DeleteFromFolder1($dir=NULL) {
if($dir == NULL)
$captchaFolder = 'folder1/';
else
$captchaFolder = $dir;
$fileTypes = '*.jpg';
$expire_time = 1;
foreach(glob($captchaFolder . $fileTypes) as $Filename) {
$FileCreationTime = filectime($Filename);
$FileAge = time() - $FileCreationTime;
if($FileAge > ($expire_time * 60))
{
unlink($Filename);
}
}
}
function DeleteFromFolder2() {
DeleteFromFolder1("folder2/");
}
}
That should work without making any major changes to your current code base.
EDIT (Adding more of a description for some clarity)
I was assuming that your code was already implemented in some way. If that is the case, a rather clunky solution is like mine above (this will allow the smallest number of edits to be made). Otherwise, you could consolidate this function to just the first one and it will work fine. DeleteFromFolder2() is merely a redirect function.
The function takes an argument $file which is null if not declared when calling the function. If $file == NULL, then it will delete folder1 by default, otherwise, it will attempt to delete the folder specified. I hope that clears things up a bit!
Good luck!
Dennis M.
Related
I have paths that goes like this template:
`/dir1/dir2/dirN/dirNplus1/dirNplus2/`
And for an example to demonstrate this template:
`/var/www/sei/modules/module1/`
I would like to be able to have a function where I could input a full path and a specific directory and get in return only the right part of the path, removing the left part including the directory specified in the parameter.
In the example given, if I would use:
`function('/var/www/sei/modules/module1/', 'sei')`
Then I would like to get the result as:
`/modules/module1/`
Any ideas on how to achieve this?
As #ADyson suggested, I wrote this code below:
const DIRETORIO_SEI = 'sei';
private static $caminho;
public static function getCaminhoModulo($append = '') {
if (self::$caminho != null) {
return self::$caminho;
}
$diretorio = explode('/', realpath(__DIR__.'/../../../'));
$caminho = '';
$incluir = false;
for ($i = 0; $i < count($diretorio); $i++) {
if ($incluir) {
$caminho = $caminho . $diretorio[$i] . '/';
}
if ($diretorio[$i] == self::DIRETORIO_SEI) {
$incluir = true;
}
}
self::$caminho = $caminho;
return $caminho.$append;
}
Idea is to store user profile photos to file server. I have done with uploading part to static folder, but I want to make It a bit dynamic.
File name is generating in following: $userid . '-' . round(microtime(true)) . '.jpg';
I want to store images based on $userid, 1000 per folder.
So it have to check if $userid <= 1000 and folder not exists, create new folder named 000001-100000.
For example if $userid = 1001 it have to check if folder not exists and create new folder with name 002001-002000 and so on.
How could I achieve it dynamically? There could be over 100 000 users, so checking in following not so best idea I think:
if (!file_exists('images/000001-001000')) && $userid <= 1000 {
mkdir('images/000001-001000', 0777, true);
}
if (!file_exists('images/001001-002000')) && $userid > 1000 && $userid <= 2000 {
mkdir('images/001001-002000', 0777, true);
}
p.s. this is not duplicated as marked, I need to store 1000 photos per folder, not to create specific folder for each user.
$count = floor($userid / 1000);
$begin = ($count * 1000) + 1;
$end = ($count + 1) * 1000;
$strBegin = $begin;
$strEnd = $end;
if($begin==1){
$strBegin = "0001";
}
if(is_dir('images/'.$strBegin.'-'.$strEnd)==false){
mkdir('images/'.$strBegin.'-'.$strEnd);
}
Try this I have created recursive method to check value. Then create directory according it
function get_thousand_value($userid,$value_min)
{
if($userid <= $value_min){
$return_val = $value_min;
}
else
{
$value_min += 1000;
$return_val =get_thousand_value($userid,$value_min);
}
return $return_val;
}
$value_min = 1000;
$last_val = get_thousand_value($userid,$value_min);
$start_val = ($last_val == 1000 ? '0001' : ($last_val - 999));
$dir_name= 'images/'.$start_val."-".$last_val;
if (!file_exists($dir_name)) {
mkdir($dir_name, 0777, true);
}
Just generate folders once. If you can't predict which folder is last, you may generate 5-50 folder more and check it with cron; do I need to generate more folders or not?
How may i able to retrieve different file extensions in a certain directory. Let say i have a folder named "downloads/", where inside that folder are different types of files like PDFs, JPEGs, DOC files etc. So in my PHP code i wanted those files be retrieved and listed with there file names and file extensions. Example: Inside "downloads/" folder are different files
downloads/
- My Poem.doc
- My Photographs.jpg
- My Research.pdf
So i wanted to view those files where i can get there file names, file extensions, and file directories. So in view will be something like this
Title: My Poem
Type: Document
Link: [url here]
Title: My Photographs
Type: Image
Link: [url here]
Title: My Research
Type: PDF
Link: [url here]
Anyone knows how to do it in php? Thanks a lot!
It's pretty simple. To be honest i don't know why didn't you searched on a php.net. They got whole lots of examples for this. Check it in here: click
Example:
<?php
function process_dir($dir,$recursive = FALSE) {
if (is_dir($dir)) {
for ($list = array(),$handle = opendir($dir); (FALSE !== ($file = readdir($handle)));) {
if (($file != '.' && $file != '..') && (file_exists($path = $dir.'/'.$file))) {
if (is_dir($path) && ($recursive)) {
$list = array_merge($list, process_dir($path, TRUE));
} else {
$entry = array('filename' => $file, 'dirpath' => $dir);
//---------------------------------------------------------//
// - SECTION 1 - //
// Actions to be performed on ALL ITEMS //
//----------------- Begin Editable ------------------//
$entry['modtime'] = filemtime($path);
//----------------- End Editable ------------------//
do if (!is_dir($path)) {
//---------------------------------------------------------//
// - SECTION 2 - //
// Actions to be performed on FILES ONLY //
//----------------- Begin Editable ------------------//
$entry['size'] = filesize($path);
if (strstr(pathinfo($path,PATHINFO_BASENAME),'log')) {
if (!$entry['handle'] = fopen($path,r)) $entry['handle'] = "FAIL";
}
//----------------- End Editable ------------------//
break;
} else {
//---------------------------------------------------------//
// - SECTION 3 - //
// Actions to be performed on DIRECTORIES ONLY //
//----------------- Begin Editable ------------------//
//----------------- End Editable ------------------//
break;
} while (FALSE);
$list[] = $entry;
}
}
}
closedir($handle);
return $list;
} else return FALSE;
}
$result = process_dir('C:/webserver/Apache2/httpdocs/processdir',TRUE);
// Output each opened file and then close
foreach ($result as $file) {
if (is_resource($file['handle'])) {
echo "\n\nFILE (" . $file['dirpath'].'/'.$file['filename'] . "):\n\n" . fread($file['handle'], filesize($file['dirpath'].'/'.$file['filename']));
fclose($file['handle']);
}
}
?>
You could use glob & pathinfo:
<?php
foreach (glob(__DIR__.'/*') as $filename) {
print_r(pathinfo($filename));
}
?>
You will try this code :
$Name = array();
$ext = array();
$downloadlink = array();
$dir = 'downloads'
while ($file= readdir($dir))
{
if ($file!= "." && $file!= "..")
{
$temp = explode(".",$file);
if (count($temp) > 1)
{
$Name[count($Name)] = $temp[0];
swich($ext)
{
case "doc" :
{
$ext[count($ext)] = "Document";
break;
}
[...]
default :
{
$ext[count($ext)] = "Error";
break;
}
}
$downloadlink[count($downloadlink)] = "http://yourdomain.com/".$dir."/".$file;
}
}
}
closedir($dir);
for($aux = 0; $aux < count($Name); $aux++)
{
echo "Name = " . $Name[$aux]."<br />
Type = " . $ext[$aux]."<br/>
Link = " . $downloadlink[$aux]."<br/>
";
}
I have a file uploader and I want the filenames to auto increment number. I don't feel the need to use a database to do this and I want to keep the code relatively clean, I'm pretty new in file upload and management in PHP so I'm not exactly sure what to do. Could anyone direct me in the right path?
Here is my current code, it just uses an md5 of a bunch of seeds.
<?php
if(isset($_FILES['imagedata']['tmp_name']))
{
// Directory related to the location of your gyazo script
$newName = 'images/' . substr(md5(rand() . time()), 0, 20) . '.png';
$tf = fopen($newName, 'w');
fclose($tf);
move_uploaded_file($_FILES['imagedata']['tmp_name'], $newName);
// Website
echo 'http://davidknag.com/' . $newName;
}
?>
<?php
if(isset($_FILES['imagedata']['tmp_name'])) {
// Directory related to the location of your gyazo script
$fileCount = count (glob ('images/*.png'));
$newName = 'images/' . ( $fileCount + 1) . '.png';
$tf = fopen($newName, 'w');
fclose($tf);
move_uploaded_file($_FILES['imagedata']['tmp_name'], $newName);
// Website
echo 'http://davidknag.com/' . $newName;
}
It just counts all .png files in the directory, increments that number by 1 and uses that as its filename.
Note that if you're storing a very large amount of files (say 10.000s), it's faster to use Joseph Lusts' method, but otherwise this will work jus tfine.
You can just have a basic text file in the given folder. Store the number in there. Read it out and increment it as needed.
It would be easiest to make a function like getNextNumber() that did the above and then you could use it as needed. You could also do this in a $_SERVER[] variable, but it would need to be reloaded from the file on server restart.
<?PHP
// a basic example
function getNextNumber() {
$count = (int)file_get_contents('yourFile.txt');
$count+=1;
file_put_contents('yourFile.txt',$count);
return $count;
}
?>
Note that if you are using this a great deal, you'll need a more advanced sequence generator since this will perform 2 file IO's on each call.
You can try the code below. It creates a file with .png extension and unique name in outdir/
$filename = uniqFile('outdir', '.png');
move_uploaded_file($_FILES['imagedata']['tmp_name'], $filename);
function uniqFile($dir, $ext)
{
if (substr($dir, -1, 1) != '/')
{
$dir .= '/';
}
for ($i=1; $i<999999; $i++)
{
if (!is_file($dir . $i . $ext))
{
return $i . $ext;
}
}
return false;
}
A little late in the game but this pair of functions does the trick and follows the familiar format of the filename followed by "(n)" and then the file extension:
incrementFileName() returns the updated filename incremented by 1 with input filename and destination directory. splitLast() is a modification of explode to only split on the last occurrence of some substring.
function incrementFileName($name,$path){
if (!array_search($name,scandir($path))) {
return $name;
} else {
$ext=splitLast($name,".")[1];
$baseFileName=splitLast(splitLast($name,".")[0],"(")[0];
$num=intval(splitLast(splitLast($name,"(")[1],")")[0])+1;
return incrementFileName($baseFileName."(".$num.").".$ext,$path);
}
}
function splitLast($string,$delim) {
$parts = explode($delim, $string);
if (!$parts || count($parts) === 1) {
$before=$string;
$after="";
} else {
$after = array_pop($parts);
$before=implode($delim, $parts);
}
return array($before,$after);
}
When handling upload, set your filename with it:
$fileName = incrementFileName($_FILES['file']['name'], $path);
This will return someFileName(1).jpg or someFileName(2).jpg etc.
function enc($length = "string") {
if(!is_numeric($length) || $length > 255 || $length < 1){
$length = rand("3","6");
}
// $randomID = substr(uniqid(sha1(crypt(md5("".time("ysia", true)."".rand())))), 0, $length);
$randomID = genUnique($length);
$count = 0;
while(glob("$randomID.*") || fetch("select * from `short` where `short` = '$randomID'") || fetch("select * from `images` where `name` = '$randomID'") || glob("img/$randomID.*") || is_numeric($randomID)){
if($count > 20){
$length++;
}
$randomID = genUnique($length);
$count++;
}
return $randomID;
}
this code is pretty old (not even using mysqli), but i figured i'd include it first
<?php
include_once "functions.php";
if(!isset($_REQUEST['api'])){
notfound("");
}
$con = connect();
$key = $_REQUEST['api'];
$ver = $_REQUEST['version'];
if($ver != "10-26-2016" || $key == "zoidberg")
{
die("Please upgrade your in4.us.exe by logging in and clicking download.");
}
if($key == "nokey"){
die("You need to keep the exe with the ini file to pair your api key. Copy ini file to same directory or redownload.");
}
$key = mysql_real_escape_string($key);
$findkey = fetch(" SELECT * from `users` where `key` = '$key' ");
if(!is_array($findkey)){
die("No user with that API Key found. Configure the INI File using your api key on in4.us");
}
$user = $findkey['username'];
if(isset($_FILES['imagedata']['tmp_name'])){
$newName = enc();
$tf = fopen("img/".$newName.".png", 'w');
fclose($tf);
move_uploaded_file($_FILES['imagedata']['tmp_name'], "img/".$newName.".png");
$domain = $_SERVER['HTTP_HOST'];
date_default_timezone_set('America/New_York');
$mysqldate = date("Y-m-d H:i:s");
$qry = mysql_query("INSERT INTO `images` (`name`, `added`, `dateadded`) VALUES ('$newName', '$user', '$mysqldate');");
if(!qry){
die('Invalid query: ' . mysql_error());
}
echo "http://$domain/$newName.png";
disconnect($con);
}else{
notfound("");
}
?>
I'm looping over all the files in a directory. Now I want to get all the functions and classes defined in each of them. From there, I can examine them further using the ReflectionClass. I can't figure out how to get all the functions and classes defined in a file though.
ReflectionExtension looks the closest to what I want, except my files aren't part of an extension. Is there some class or function I'm overlooking?
Great question. get_declared_classes and get_defined_functions could be a good starting point. You would have to take note of what classes / functions are already defined when trying to determine what's in a given file.
Also, not sure what your end goal is here, but tools such as PHP Depend or PHP Mess Detector may do something similar to what you want. I'd recommend checking them out as well.
This is the best I could come up with (courtesy):
function trimds($s) {
return rtrim($s,DIRECTORY_SEPARATOR);
}
function joinpaths() {
return implode(DIRECTORY_SEPARATOR, array_map('trimds', func_get_args()));
}
$project_dir = '/path/to/project/';
$ds = array($project_dir);
$classes = array();
while(!empty($ds)) {
$dir = array_pop($ds);
if(($dh=opendir($dir))!==false) {
while(($file=readdir($dh))!==false) {
if($file[0]==='.') continue;
$path = joinpaths($dir,$file);
if(is_dir($path)) {
$ds[] = $path;
} else {
$contents = file_get_contents($path);
$tokens = token_get_all($contents);
for($i=0; $i<count($tokens); ++$i) {
if(is_array($tokens[$i]) && $tokens[$i][0] === T_CLASS) {
$i += 2;
$classes[] = $tokens[$i][1];
}
}
}
}
} else {
echo "ERROR: Could not open directory '$dir'\n";
}
}
print_r($classes);
Wish I didn't have to parse out the files and loop over all the tokens like this.
Forgot the former solutions prevents me from using reflection as I wanted. New solution:
$project_dir = '/path/to/project/';
$ds = array($project_dir);
while(!empty($ds)) {
$dir = array_pop($ds);
if(($dh=opendir($dir))!==false) {
while(($file=readdir($dh))!==false) {
if($file[0]==='.') continue;
$path = joinpaths($dir,$file);
if(is_dir($path)) {
$ds[] = $path;
} else {
try{
include_once $path;
}catch(Exception $e) {
echo 'EXCEPTION: '.$e->getMessage().PHP_EOL;
}
}
}
} else {
echo "ERROR: Could not open directory '$dir'\n";
}
}
foreach(get_declared_classes() as $c) {
$class = new ReflectionClass($c);
$methods = $class->getMethods();
foreach($methods as $m) {
$dc = $m->getDocComment();
if($dc !== false) {
echo $class->getName().'::'.$m->getName().PHP_EOL;
echo $dc.PHP_EOL;
}
}
}