I have a api, which will upload the images of the users to server.
It will take the images in base64 format and send that to server. But the problem is for some user it will take long time, and for some user it works well.
I am not getting why this is happening. But the destination directory is a having 700GB of data.
code for uploading :
`
$file will be having base64 format of image
$this->file = $file;
if ($this->id && !empty($this->path) && !is_null($file)) {
$this->storeFilenameForRemove();
}
if ($file instanceof File) {
if (isset($this->path)) {
$this->temp = $this->path;
$this->path = null;
} else {
$this->path = 'initial';
}
} else if (gettype($file) == 'string') {
if (preg_match('/data:(\w+)\/(\w+);base64,/i', $file, $matches)) {
if ($matches) {
$file = preg_replace('/data:(\w+)\/(\w+);base64,/i', '', $file);
$tmpFile = Array();
$tmpFile['data'] = base64_decode( str_replace(' ', '+', $file) );
if ($matches[1] === 'image') {
$tmpFile['name'] = uniqid().'.png';
} else {
$tmpFile['name'] = uniqid().'.'.$matches[2];
}
$tmpFile['handle'] = fopen( $this->getUploadRootDir().'/'.$tmpFile['name'], 'w' );
// inject the raw image data into the new file
fwrite( $tmpFile['handle'], $tmpFile['data'] );
fclose( $tmpFile['handle'] );
$this->path = $tmpFile['name'];
}
}
} else {
$this->file = $file;
}`
I'm not sure if executing a preg_match on a base64 encoded string is a good idea, while I'm not sure that fixes all of your problems regarding speed I'm positive that implementing a different check for base64 encoded strings would improve the speed.
Replace the following:
if (preg_match('/data:(\w+)\/(\w+);base64,/i', $file, $matches)) {
with this
if ( base64_encode(base64_decode($file)) === $file){
Related
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 am developing a module for my client to upload and browse file in Opencart.
when I am uploading file from my back-end server I am getting the output as file.zip.xyzasdf. Where I just want to remove this .xyzasdf
Can any one suggest me how to remove sanitize from the following code...
public function upload() {
$this->load->language('catalog/download');
$json = array();
// Check user has permission
if (!$this->user->hasPermission('modify', 'catalog/download')) {
$json['error'] = $this->language->get('error_permission');
}
if (!$json) {
if (!empty($this->request->files['file']['name']) && is_file($this->request->files['file']['tmp_name'])) {
// Sanitize the filename
$filename = basename(html_entity_decode($this->request->files['file']['name'], ENT_QUOTES, 'UTF-8'));
// Validate the filename length
if ((utf8_strlen($filename) < 3) || (utf8_strlen($filename) > 128)) {
$json['error'] = $this->language->get('error_filename');
}
// Allowed file extension types
$allowed = array();
$extension_allowed = preg_replace('~\r?\n~', "\n", $this->config->get('config_file_ext_allowed'));
$filetypes = explode("\n", $extension_allowed);
foreach ($filetypes as $filetype) {
$allowed[] = trim($filetype);
}
if (!in_array(strtolower(substr(strrchr($filename, '.'), 1)), $allowed)) {
$json['error'] = $this->language->get('error_filetype');
}
// Allowed file mime types
$allowed = array();
$mime_allowed = preg_replace('~\r?\n~', "\n", $this->config->get('config_file_mime_allowed'));
$filetypes = explode("\n", $mime_allowed);
foreach ($filetypes as $filetype) {
$allowed[] = trim($filetype);
}
if (!in_array($this->request->files['file']['type'], $allowed)) {
$json['error'] = $this->language->get('error_filetype');
}
// Check to see if any PHP files are trying to be uploaded
$content = file_get_contents($this->request->files['file']['tmp_name']);
if (preg_match('/\<\?php/i', $content)) {
$json['error'] = $this->language->get('error_filetype');
}
// Return any upload error
if ($this->request->files['file']['error'] != UPLOAD_ERR_OK) {
$json['error'] = $this->language->get('error_upload_' . $this->request->files['file']['error']);
}
} else {
$json['error'] = $this->language->get('error_upload');
}
}
if (!$json) {
$file = $filename . '.' . token(32);
move_uploaded_file($this->request->files['file']['tmp_name'], DIR_FOLDER . $file);
$json['filename'] = $file;
$json['mask'] = $filename;
$json['success'] = $this->language->get('text_upload');
}
$this->response->addHeader('Content-Type: application/json');
$this->response->setOutput(json_encode($json));
}
Any help would be greatly appreciated...
Thanks
Removing the random string that is added to the filename is simple. Just change
move_uploaded_file($this->request->files['file']['tmp_name'], DIR_UPLOAD . $file);
to:
move_uploaded_file($this->request->files['file']['tmp_name'], DIR_UPLOAD . $filename);
But keep in mind that this will bring problems.
OpenCart saves the random string in the database at the time of file upload, so it will later use it to identify the file.
If you delete this feature, the uploaded files in the admin panel will not be available.
Im trying to upload a file image/file type from mobile app and store that image in the backend. Im using Yii2 framework API to do this. And im using postman to check the API. Im running the below in my action.
/*Uploading documents*/
public function actionUploading_doc() {
$uploads = \yii\web\UploadedFile::getInstanceByName('upfile');
print_r($uploads);exit;
if (empty($uploads)){
return "Must upload at least 1 file in upfile form-data POST";
}
foreach ($uploads as $file){
$filename = time() . $image->name;
$path = "uploads/" . $filename;
$file->saveAs($path);
}
}
When i run this as POST method from postman.. and print the value of $uploads im getting empty value. It mean its not coming to controller.
Please help me in solving this.
For me this is what i did without the UploadFile class
/*Uploading documents*/
public function actionUploading() {
$uploads = \yii\web\UploadedFile::getInstanceByName('upfile');
\yii::$app->request->enableCsrfValidation = false;
$filename = $uploads->name;
$path = "http://localhost/projects/YiiRestful/api/web/uploads/".$filename;
$putdata = fopen("php://input", "r");
// make sure that you have /web/upload directory (writeable)
// for this to work
$path = "uploads/".$filename;
$fp = fopen($path, "w");
while ($data = fread($putdata, 1024))
fwrite($fp, $data);
/* Close the streams */
fclose($fp);
fclose($putdata);
}
I would try something like this... (not tested)
public function actionUploadingDoc() { // good practice to use camel case for methods
$uploads = \yii\web\UploadedFile::getInstances('upfile');
if (empty($uploads)){
return false;
// handle error reporting somewhere else
}
$path = 'uploads/'; // set your path
foreach ($uploads as $upload){
$filename = $path . time() .'_'. $upload->name ;
$upload->saveAs($filename);
}
return true;
}
You can use base64 string to uplod. define function inside controller like this
public function base64_to_jpeg($base64_string, $output_file) {
$path="your/real/path/";
// open the output file for writing
$ifp = fopen( $path.$output_file, 'wb' );
// split the string on commas
// $data[ 0 ] == "data:image/png;base64"
// $data[ 1 ] == <actual base64 string>
$data = explode( ',', $base64_string );
if(count($data)>1) {
$dataText=$data[ 1 ];
} else {
$dataText=$base64_string;
}
// we could add validation here with ensuring count( $data ) > 1
fwrite( $ifp, base64_decode( $dataText ) );
// clean up the file resource
fclose( $ifp );
return $output_file;
}
And use inside action as
public function actionUpload(){
$imgName=md5(uniqid()).'.jpg';
$this->base64_to_jpeg($base64_string, $imgName);
}
I know, there are many solutions for this question, but unfortunately I couldn't solve it, Here is my upload code:
public static function upload(&$file, $destinationDir = "", $destinationName = "", $secure = true)
{
$ret = false;
if (isset($file['tmp_name']) && isset($file['name']))
{
if ($destinationName == '')
{
$destinationName = $file['name'];
}
$destinationFile = $destinationDir . '/' . $destinationName;
if (move_uploaded_file($file['tmp_name'], $destinationFile))
{
if ($secure)
{
chmod($destinationFile, 0644); // without execution permissions if it is possible
}
$ret = true;
}
}
return $ret;
}
1: How can I rename file while uploading to server ?
2: If file name is exist then how to rename it automatically?
Thanks in advance
Use file_exists for this case :
public static function upload(&$file, $destinationDir = "", $destinationName = "", $secure = true){
$ret = false;
if(isset($file['tmp_name']) && isset($file['name'])){
if ($destinationName == ''){
$destinationName = md5($file['name']);
}
$destinationFile = $destinationDir.'/'.$destinationName;
if(file_exists($destinationFile)){
// Change the destination file name if it exists
$destinationFile = $destinationDir.'/'.md5($destinationName.rand());
}
if (move_uploaded_file($file['tmp_name'], $destinationFile)){
if($secure){
chmod($destinationFile, 0644); // without execution permissions if it is possible
}
$ret = true;
}
}
Note:
move_uploaded_file — Moves an uploaded file to a new location
structured like this
bool move_uploaded_file ( string $filename , string $destination )
in $destination parameter you give the name of your new uploaded file. Name your file to something that unique. Whatever !, so don't worry about this
I tried to replace single quotes in a large XML file(110MB) with this code but an error occured. I need a code that can handle atleast 3GB XML file.
Error Message:
Fatal error: Allowed memory size of 134217728 bytes exhausted
(tried to allocate 20449728 bytes) in C:\xampp\htdocs\replace.php on
line 10
<?php
replace_file('electronics.xml', "'", "'");
function replace_file($path, $string, $replace)
{
$file = fopen($path, 'a+');
while (feof($file) === false)
{
$str=file_get_contents($path);
$str=str_replace($string, $replace, fgets($file));
}
fclose($file);
}
echo "replace done";
?>
Reading a large file into php is not recommended. Call a command line that is appropriate, like sed
Reference: http://www.grymoire.com/Unix/Sed.html
Simplify:
$str = str_replace( "'","'",file_get_contents('electronics.xml'));
This is just very wrong:
Opening XML
$file = fopen($path, 'a+');
While Loop for no reason, fgets reads to end of file, so loop completes on first iteration.
while (feof($file) === false)
{
reading in entire contents of same file file again, for no purpose
$str=file_get_contents($path);
Reading in entire file, no length specified, so reading to EOF
$str=str_replace($string, $replace, fgets($file));
}
fclose($file);
Nothing accomplished.
////
//PHP 5.3 + Class find and replace string in files
//
//by Bruce Afruz
//
//2013
//
//example usage for single file:
//
//$new = new fileReplacement('./');
//$new->setExt("check.php");
//$new->changeContents("hello", "goodbye");
//
//example usage for multiple files:
//
//$new = new fileReplacement('./test');
//$new->setExt("*.html");
//$new->changeContents("hello", "goodbye");
//
//to change directory:
//
//$new = new fileReplacement('./test');
//$new->setDir("./test2");
//$new->setExt("*.html");
//$new->changeContents("hello", "goodbye");
////
class fileReplacement
{
private $ext , $dir ;
public function getDir() {
return $this->dir;
}
public function setDir($dir) {
$this->dir = $dir;
}
public function getExt() {
return $this->ext;
}
public function setExt($ext) {
$this->ext = $ext;
}
function __construct($dir) {
$this->dir = $dir;
}
public function rglob($pattern = '*', $flags = 0, $path = '') {
chdir($this->getDir());
$paths = glob($path . '*', GLOB_MARK | GLOB_ONLYDIR | GLOB_NOSORT);
$files = glob($path . $pattern, $flags);
foreach ($paths as $path) {
$files = array_merge($files, $this->rglob($pattern, $flags, $path));
}
return $files;
}
public function changeContents($replace , $sentence , $flags = 0, $path = '') {
$all = $this->rglob($this->getExt() , $flags, $path);
foreach ($all as $file) {
$filename = $file;
$handle = fopen($filename, "r");
$contents = fread($handle, filesize($filename));
fclose($handle);
$contents = str_replace($replace , $sentence, $contents);
if (is_writable($filename)) {
if (!$handle = fopen($filename, 'w+')) {
echo "Cannot open file ($filename)
";
exit;
}
// Write $contents to our opened file.
if (fwrite($handle, $contents) === FALSE) {
echo "Cannot write to file ($filename)
";
exit;
}
echo "Success, wrote content to file ($filename)
";
fclose($handle);
} else {
echo "The file $filename is not writable
";
}
}
}}