I am trying to divide CSV file into 6mb files. Following is the code I have tried.
$file = 'upload/L_10001_20200916183801.csv';
$files = SplitCSVBySize($file, 10001);
function SplitCSVBySize($Existingfiles, $AccountId, $splitSize = "") {
$fh = fopen($Existingfiles, 'r');
$headers = fgetcsv($fh);
$files = array();
$filepath = 'upload/' . 'L_' . $AccountId . '_' . date('YmdHis') . '.csv';
$files[] = $filepath;
$currentFile = $filepath;
$outputFile = fopen($filepath, 'w');
fputcsv($outputFile, $headers);
$rows = 0;
while (!feof($fh)) {
if ($row = $rowPri = fgetcsv($fh))
{
if(filesize($filepath) < 6000000){
fputcsv($outputFile, $row);
} else {
fclose($outputFile);
$rows = 0;
$filepath = 'upload/' . 'L_' . $AccountId . '_' . date('YmdHis') . '.csv';
$files[] = $filepath;
$currentFile = $filepath;
$outputFile = fopen($filepath, 'w');
fputcsv($outputFile, $headers);
fputcsv($outputFile, $row);
}
$rows++;
}
}
fclose($outputFile);
fclose($fh);
return $files;
}
Here challenge is I am not able to check filesize because It always returns same size as it was at very first check. Plese help here, what is wrong or any suggestion.
First of all. function filesize (as well as all other derivatives from stat) is cached. That means, once called on some file, its result will remain the same for the same file.
You need to call clearstatcache() prior to calling this function, to clear the cache.
Second. You don't need to call filesize to obtain the size of the opened file.
You can call fstat on the opened file handle and use 'size' item of the returned array . E.g.:
...
$st = filestat($outputFile);
if($st['size'] < 6000000){
...
And at last you don't need to know size of the file, since you have current file position which is, when writing to the file, equals to its size. You can use ftell to obtain that. I.e.
...
if (ftell($outputFile) < 6000000) {
...
Related
I'm trying to make a visitor counter with php that will create yy-mm-dd.txt everyday and contain the number of visitors that day and after 12 AM it will create a new yy-mm-dd.txt file.
As example today is 2019-06-02 so the text file will be 2019-06-02.txt and in the next day, 2019-06-03.txt file will be automatically created.
Here is what I tried but it is not creating new 2019-06-03.txt file after 12 AM. It keeps the same 2019-06-02.txt file
<?php
$date = date('Y-m-d');
$fp = fopen('dates/'.$date.'.txt', "r");
$count = fread($fp, 1024);
fclose($fp);
$count = $count + 1;
$fp = fopen('dates/'.$date.'.txt', "w");
fwrite($fp, $count);
fclose($fp);
?>
How to fix it?
Your code should be working fine. We can also add is_dir and file_exists checks, and we can use either fopen, fwrite and fclose or file_get_content/file_put_content, if we like. We can also add a default_timezone such as:
date_default_timezone_set("America/New_York");
Then, our code would look like something similar to:
date_default_timezone_set("America/New_York");
$dir = 'dates';
if (!is_dir($dir)) {
mkdir($dir, 0755, true);
}
$count = 1;
$date = date('Y-m-d');
$filename = $dir . '/' . $date . '.txt';
if (!file_exists($filename)) {
$fp = fopen($filename, "w");
fwrite($fp, $count);
fclose($fp);
} else {
$count = (int) file_get_contents($filename) + 1;
if ($count) {
file_put_contents($filename, $count);
} else {
print("Something is not right!");
}
}
Better use file_get_contents then file_put_contents:
<?php
$count = 1;
$content = file_get_contents(date('Y-m-d').'txt');
if($content !== FALSE){
$count+=(int)$content;
}
file_put_contents(date('Y-m-d').'txt', $count);
?>
Reading the file for the image url and calling the copy function.
imagecopy.txt
https://server.com/2017/12/check.png
https://server.com/2017/12/contacts.png
https://server.com/2018/06/CDP.bmp
https://server.com/module-acculturation-1.png
While copying the files from the url, getting the failed to open stream: Invalid argument error only on inside while loop. but works for the last record if the file has more files.
<?php
$file=fopen("imagecopy.txt","r") or exit("Unable to open file!");
while (!feof($file))
{
$source = fgets($file);
$imagename = explode("/", $source);
$pathname = 'uploads/' . date("Y") . '/' . date("m") . '/';
if (!is_dir($pathname))
{
mkdir($pathname, 0777, true);
}
$destination = $pathname.end($imagename);
copyimageURL($source, $destination);
}
fclose($file);
function copyimageURL($source, $destination)
{
echo $source;
echo "<br>";
echo $destination;
copy($source, $destination);
}
?>
1.Working fine with singe record
2.Copying the last image only if the file has more images list.
I'm guessing imagecopy.txt you're reading ends in a newline, which makes the last line of the file blank.
If you change
$source = fgets($file);
to
$source = trim(fgets($file));
if( empty($source) ) continue;
it should work fine
Try this:
if ($file) {
while (($name = fgets($file)) !== false) {
$imagename = basename($name);
$pathname = 'uploads/' . date("Y") . '/' . date("m") . '/';
if (!is_dir($pathname))
mkdir($pathname, 0777, true);
$destination = $pathname.$imagename;
copyimageURL(trim($name), $destination);
}
fclose($file);
}
I would like to save each newly generated PDF file with a unique filename to the "receipts" directory after generating the PDF using the FPDF library... As it is now, the PDF is overwritten each time. Can I append a time-stamp to the PDF filename? Example --->( /receipt_month-day-year-hour-seconds.pdf )
Absolute uniqueness desired, but not super critical.
$pdf->Output('receipts/receipt.pdf', 'F');
An easy (but not foolproof) way of ensuring a filename is unique would be to add a microtime timestamp to the filename. Microtime includes thousanths of a second, so would probably work unless your site has a lot of traffic:
$pdf->Output('receipts/receipt-' . microtime(true) . '.pdf', 'F');
If you want your timestamp to be like receipt_12-26-2017.pdf, then:
$pdf->Output('receipts/receipt_' . date("m-d-Y") . '.pdf', 'F');
If you really want to ensure your filenames are unique per directory, you could do something like this:
<?php
function get_filenames($source_dir, $include_path = FALSE, $_recursion = FALSE)
{
static $_filedata = array();
if ($fp = #opendir($source_dir))
{
// reset the array and make sure $source_dir has a trailing slash on the initial call
if ($_recursion === FALSE)
{
$_filedata = array();
$source_dir = rtrim(realpath($source_dir), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
}
while (FALSE !== ($file = readdir($fp)))
{
if (#is_dir($source_dir.$file) && strncmp($file, '.', 1) !== 0)
{
get_filenames($source_dir.$file.DIRECTORY_SEPARATOR, $include_path, TRUE);
}
elseif (strncmp($file, '.', 1) !== 0)
{
$_filedata[] = ($include_path == TRUE) ? $source_dir.$file : $file;
}
}
return $_filedata;
}
else
{
return FALSE;
}
}
function force_unique_filename( $dir_list, $file_name, $x = 2 )
{
/**
* Dir list may be an array of file names, or in the case of
* cURL, the list may be supplied as a string. If an array, we
* just convert the array to a string so it is checked as a string.
*/
if( is_array( $dir_list ) )
{
$dir_list = implode( ' ', $dir_list );
}
while( strpos( $dir_list, $file_name ) !== FALSE )
{
// Use pathinfo to break apart the filename
$info = pathinfo( $file_name );
// Get the file extension of the file
$ext = '.' . $info['extension'];
// Get the name of the file without extension
$file_name = basename( $file_name, $ext );
// Remove the filename suffix before adding a new one
$pattern = '/\(\d+\)/';
$replacement = '';
$file_name = preg_replace( $pattern, $replacement, $file_name );
// Add new filename suffix
$file_name .= '(' . (string) $x . ')' . $ext;
// Increment the number we are using in a filename suffix "($x)"
$x++;
}
return $file_name;
}
// -----------------------------------------------------------------------
// This directory should be an absolute path...
$source_dir = './receipts';
// The desired filename
$filename = 'receipt_' . date("m-d-Y") . '.pdf';
// Get all of the filenames in this directory
$filenames = get_filenames( $source_dir, FALSE, FALSE );
// Get the unique filename
$unique_filename = force_unique_filename( $filenames, $filename );
$pdf->Output('receipts/' . $unique_filename, 'F');
I'm trying to make it retrieve the image files on the server but it won't work if there is a space in the name of the image file .. for example there is a space between dead and air , even if I escape it after adding %20, the function returns an empty string .. but if it is a file with no space in the name like 'http://www.m.trialsite.com/images/thumb/Espresso.jpg'; It will work ! .. where am I going wrong ?
$filename = 'http://www.m.trialsite.com/images/thumb/dead air.jpg';
function readfile_chunked($filename,$retbytes=true) {
$chunksize = 1*(1024*1024); // how many bytes per chunk
$buffer = '';
$cnt =0;
// $handle = fopen($filename, 'rb');
$filename = str_replace(' ','%20',$filename);
$handle = fopen($filename, 'rb');
if ($handle === false) {
return false;
}
$filename = str_replace(' ','%20',$filename);
while (!feof($handle)) {
$buffer = fread($handle, $chunksize);
echo $buffer; var_dump($buffer); exit;
ob_flush();
flush();
if ($retbytes) {
$cnt += strlen($buffer);
}
}
$status = fclose($handle);
if ($retbytes && $status) {
return $cnt; // return num. bytes delivered like readfile() does.
}
return $status;
}
use preg_replace("/\s+/","_",$nome); to rename the files and then recovers it it will work
$directory = '/public_html/testfolder/';//example
if ($handle = opendir($directory)) {
while (false !== ($fileName = readdir($handle))) {
$newName = preg_replace("/\s+/","_",$fileName);
rename($directory . $fileName, $directory . $newName);
}
closedir($handle);
}
What if you are doing like this:
$filename = str_replace(' ','%20', 'http://www.m.trialsite.com/images/thumb/dead air.jpg');
is there any pretty solution in PHP which allows me to expand filename with an auto-increment number if the filename already exists? I dont want to rename the uploaded files in some unreadable stuff. So i thought it would be nice like this: (all image files are allowed.)
Cover.png
Cover (1).png
Cover (2).png
…
First, let's separate extension and filename:
$file=pathinfo(<your file>);
For easier file check and appending, save filename into new variable:
$filename=$file['filename'];
Then, let's check if file already exists and save new filename until it doesn't:
$i=1;
while(file_exists($filename.".".$file['extension'])){
$filename=$file['filename']." ($i)";
$i++;
}
Here you go, you have a original file with your <append something> that doesn't exist yet.
EDIT:
Added auto increment number.
Got it:
if (preg_match('/(^.*?)+(?:\((\d+)\))?(\.(?:\w){0,3}$)/si', $FILE_NAME, $regs)) {
$filename = $regs[1];
$copies = (int)$regs[2];
$fileext = $regs[3];
$fullfile = $FILE_DIRECTORY.$FILE_NAME;
while(file_exists($fullfile) && !is_dir($fullfile))
{
$copies = $copies+1;
$FILE_NAME = $filename."(".$copies.")".$fileext;
$fullfile = $FILE_DIRECTORY.$FILE_NAME;
}
}
return $FILE_NAME;
You can use this function below to get unique name for uploading
function get_unique_file_name($path, $filename) {
$file_parts = explode(".", $filename);
$ext = array_pop($file_parts);
$name = implode(".", $file_parts);
$i = 1;
while (file_exists($path . $filename)) {
$filename = $name . '-' . ($i++) . '.' . $ext;
}
return $filename;
}
Use that function as
$path = __DIR__ . '/tmp/';
$fileInput = 'userfile';
$filename = $path .
get_unique_file_name($path, basename($_FILES[$fileInput]['name']));
if (move_uploaded_file($_FILES[$fileInput]['tmp_name'], $filename)) {
return $filename;
}
You can get working script here at github page
Use file_exists() function and rename() function to achieve what you're trying to do!