I'm Vietnamese and i want to upload a utf-8 filename like
Tên Tệp Tiếng Việt.JPG
Here is my code
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>utf-8</title>
</head>
<body>
<?php
if(isset($_POST["submit"])) {
if($_FILES["upload"]["error"] > 0 ) echo "FILE ERROR!";
else
{
$base_dir = "D:/";
$fn = $_FILES["upload"]["name"];
$fn2 = $base_dir.$fn;
move_uploaded_file($_FILES["upload"]["tmp_name"],$fn2);
}
}
?>
<form action="" method="post" enctype="multipart/form-data" name="form1" id="form1">
<input type="file" name="upload" id="upload" />
<input type="submit" name="submit" id="submit" value="Send" />
</form>
</body>
</html>
but when i upload that i see on my computer D:\ has a file like
Tên Tệp Tiếng Việt.JPG
How to fix that thanks
I'm on Windows 8 chinese version, and I deal with similar problem with this:
$filename = iconv("utf-8", "cp936", $filename);
cp stands for Code page and cp936 stands for Code page 936, which is the default code page of simplified chinese version of Windows.
So I think maybe your problem could be solved in a similar way:
$fn2 = iconv("UTF-8","cp1258", $base_dir.$fn);
I'm not quite sure whether the default code page of your OS is 1258 or not, you should check it yourself by opening command prompt and type in command chcp. Then change 1258 to whatever the command give you.
UPDATE
It seems that PHP filesystem functions can only handle characters that are in system codepage, according to this answer. So you have 2 choices here:
Limit the characters in the filename to system codepage - in your case, it's 437. But I'm pretty sure that code page 437 does not include all the vietnamese characters.
Change your system codepage to the vietnamese one: 1258 and convert the filename to cp1258. Then the filesystem functions should work.
Both choices are deficient:
Choice 1: You can't use vietnamese characters anymore, which is not what you want.
Choice 2: You have to change system code page, and filename characters are limited to code page 1258.
UPDATE
How to change system code page:
Go to Control Panel > Region > Administrative > Change system locale and select Vietnamese(Vietnam) in the drop down menu.
This meta has no effect:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
because the web server has already sent Content-Type header, and thus decided what the encoding will be. Web browsers send forms in the same encoding. The meta is useful when user is off-line.
So you have to sned http header Content-Type by yourself:
<?php header("Content-Type: text/html; charset=utf-8"); ?>
ensure that you put this before any html, content or whatever is sent.
Alternatively, accept-charset tag on form should work as weel:
<form accept-charset="utf-8">
I am Persian and I have same problem with utf-8 character in my language.
I could solve my problem with this code:
$fn = $_FILES["upload"]["name"]; // name of file have some utf-8 characters
$name=iconv('utf-8','windows-1256', str_replace('ی', 'ي', $fn));
move_uploaded_file($_FILES["upload"]["tmp_name"],$name );
I am not sure about vientam language but maybe you can use the same code as above with a few changes:
$fn = $_FILES["upload"]["name"]; // name of file have some utf-8 characters
$name=iconv('utf-8','cp936', $fn);
move_uploaded_file($_FILES["upload"]["tmp_name"],$name );
The only solution I have found so far.. (2014 year):
1) I dont store files on my FTP in UTF-8 string. Instead, i use this function, to rename the uploaded files:
<?php
// use your custom function.. for example, utf8_encode
$newname = utf8_encode($_FILES["uploadFile"]["name"]);
move_uploaded_file($_FILES["uploadFile"]["tmp_name"], $newname);
?>
2) Now you can rename (or etc) $newname;
For a start get detecting filename encoding (before uploading).
print_r($_FILES["upload"]);
Insert filename to decoder and check encoding.
Sorry! your question is about file name.
You must save your file name with iconv but read without this.
for saving:
<?php
$name = $_FILES['photo']['name'];
$unicode = iconv('windows-1256', 'utf-8', $name);
move_uploaded_file($_FILES['photo']['tmp_name'], 'photos/' . $name);
mysql_query("INSERT INTO `photos` (`filename`) VALUES ('{$unicode}')");
?>
for reading:
<?php
$images = mysql_query('SELECT * FROM `photos`');
if($images && mysql_num_rows($images) > 0) {
while($image = mysql_fetch_assoc($images)) {
$name = iconv('utf-8', 'windows-1256', $image['filename']);
echo '<img src="photos/' . $name . '"/>';
}
mysql_free_result($images);
}?>
function convToUtf8($str)
{
if( mb_detect_encoding($str,"UTF-8, ISO-8859-1, GBK")!="UTF-8" )
{
return iconv("gbk","utf-8",$str);
}
else
{
return $str;
}
}
$filename= convToUtf8($filename) ;
try this
$imgname = $_FILES['img'] ['name'] ;
$imgsize = $_FILES['img'] ['size'] ;
$imgtmpname = $_FILES['img'] ['tmp_name'] ;
$imgtype = $_FILES['img'] ['type'] ;
$size = 1024;
$imgtypes = array('image/jpeg','image/gif','image/png');
$folder = "up";
if(empty($imgname)){
echo "Shose ur photo";
}else if(!in_array($imgtype,$imgtypes)){
echo "this photo type is not avalable";
}else if($imgsize > $size){
echo "this photo is dig than 6 MB";
}else if($imgwidth > 5000){
echo "the file is to big";
}
else{
move_uploaded_file($imgtmpname, $folder, $filename);
}
You can use this
$fn2 = basename($_FILES['upload']['name']);
Related
I am working on a page that allows the user to "upload" multiple files at once (they are stored locally in folders relative to their type).
My problem is that when I try to pass $upFile1 and $fileInfo1 to writeResults() to update $fileInfo1 with information about $upFile1, the echoed result is empty.
I did some research and this appears to be a scoping issue, but I'm not sure about the best way to get around this having just started learning PHP last month.
Any help would be greatly appreciated.
foo.html
<!DOCTYPE HTML>
<html>
<head>
<title>File Upload</title>
</head>
<body>
<form method="post" action="foo.php" enctype="multipart/form-data">
<p>
<b>File 1:</b><br>
<input type="file" name="upFile1"><br/>
<br/>
<b>File 2:</b><br>
<input type="file" name="upFile2"><br/>
<br/>
</p>
<p>
<input type="submit" name="submit" value="Upload Files">
</p>
</form>
</body>
</html>
foo.php
<?php
$upFile1 = $_FILES['upFile1'];
$upFile2 = $_FILES['upFile2'];
$fileInfo1 = "";
$fileInfo2 = "";
// Check if directories exist before uploading files to them
if (!file_exists('./files/images')) mkdir('./files/images', 0777, true);
if (!file_exists('./files/text')) mkdir('./files/text', 0777, true);
// Copies the file from the source input to its corresponding folder
function copyTo($source) {
if (($source['type'] == 'image/jpg') || ($source['type'] == 'image/png')) {
#copy($source['tmp_name'], "./files/images/".$source['name']);
}
if ($source['type'] == 'text/plain') {
#copy($source['tmp_name'], "./files/text/".$source['name']);
}
}
// Outputs file data for input file to destination
function writeResults($source, $destination) {
$destination .= "You sent: ";
$destination .= $source['name'];
$destination .= ", a ";
$destination .= $source['size'];
$destination .= "byte file with a mime type of ";
$destination .= $source['type'];
$destination .= ".";
// echoing $destination outputs the correct information, however
// $fileInfo1 and $fileInfo2 aren't affected at all.
}
// Check if both of the file uploads are not empty
if ((!empty($upFile1['name'])) || (!empty($upFile2['name']))) {
// Check if the first file upload is not empty
if (!empty($upFile1['name'])) {
copyTo($upFile1);
writeResults($upFile1, $fileInfo1);
}
// Check if the second file upload is not empty
if (!empty($upFile2['name'])) {
copyTo($upFile2);
writeResults($upFile2, $fileInfo2);
}
} else {
die("No input files specified.");
}
?>
<!DOCTYPE HTML>
<html>
<head>
<title>File Upload</title>
</head>
<body>
<p>
<!-- This is empty -->
<?php echo "$fileInfo1"; ?>
</p>
<p>
<!-- This is empty -->
<?php echo "$fileInfo2"; ?>
</p>
</body>
</html>
you are passing the values of $fileInfo1 and $fileInfo2 but they are empty. After that there is no relation between the $destination value and the fileininfo values.
Change your function to return the $destination value.
Change your writeResults command to $fileInfo1 = writeResults($upFile1);
Use the & sign to pass variables by reference
function addOne(&$x) {
$x = $x+1;
}
$a = 1;
addOne($a);
echo $a;//2
function writeResults($source, &$destination) {
$destination .= "You sent: ";
$destination .= $source['name'];
$destination .= ", a ";
$destination .= $source['size'];
$destination .= "byte file with a mime type of ";
$destination .= $source['type'];
$destination .= ".";
// echoing $destination outputs the correct information, however
// $fileInfo1 and $fileInfo2 aren't affected at all.
}
Adding & in front of $destination will pass the variable by reference, instead of by value. So modifications made in the function will apply to the variable passed, instead of a copy inside the function.
I'm Vietnamese and i want to upload a utf-8 filename like
Tên Tệp Tiếng Việt.JPG
Here is my code
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>utf-8</title>
</head>
<body>
<?php
if(isset($_POST["submit"])) {
if($_FILES["upload"]["error"] > 0 ) echo "FILE ERROR!";
else
{
$base_dir = "D:/";
$fn = $_FILES["upload"]["name"];
$fn2 = $base_dir.$fn;
move_uploaded_file($_FILES["upload"]["tmp_name"],$fn2);
}
}
?>
<form action="" method="post" enctype="multipart/form-data" name="form1" id="form1">
<input type="file" name="upload" id="upload" />
<input type="submit" name="submit" id="submit" value="Send" />
</form>
</body>
</html>
but when i upload that i see on my computer D:\ has a file like
Tên Tệp Tiếng Việt.JPG
How to fix that thanks
I'm on Windows 8 chinese version, and I deal with similar problem with this:
$filename = iconv("utf-8", "cp936", $filename);
cp stands for Code page and cp936 stands for Code page 936, which is the default code page of simplified chinese version of Windows.
So I think maybe your problem could be solved in a similar way:
$fn2 = iconv("UTF-8","cp1258", $base_dir.$fn);
I'm not quite sure whether the default code page of your OS is 1258 or not, you should check it yourself by opening command prompt and type in command chcp. Then change 1258 to whatever the command give you.
UPDATE
It seems that PHP filesystem functions can only handle characters that are in system codepage, according to this answer. So you have 2 choices here:
Limit the characters in the filename to system codepage - in your case, it's 437. But I'm pretty sure that code page 437 does not include all the vietnamese characters.
Change your system codepage to the vietnamese one: 1258 and convert the filename to cp1258. Then the filesystem functions should work.
Both choices are deficient:
Choice 1: You can't use vietnamese characters anymore, which is not what you want.
Choice 2: You have to change system code page, and filename characters are limited to code page 1258.
UPDATE
How to change system code page:
Go to Control Panel > Region > Administrative > Change system locale and select Vietnamese(Vietnam) in the drop down menu.
This meta has no effect:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
because the web server has already sent Content-Type header, and thus decided what the encoding will be. Web browsers send forms in the same encoding. The meta is useful when user is off-line.
So you have to sned http header Content-Type by yourself:
<?php header("Content-Type: text/html; charset=utf-8"); ?>
ensure that you put this before any html, content or whatever is sent.
Alternatively, accept-charset tag on form should work as weel:
<form accept-charset="utf-8">
I am Persian and I have same problem with utf-8 character in my language.
I could solve my problem with this code:
$fn = $_FILES["upload"]["name"]; // name of file have some utf-8 characters
$name=iconv('utf-8','windows-1256', str_replace('ی', 'ي', $fn));
move_uploaded_file($_FILES["upload"]["tmp_name"],$name );
I am not sure about vientam language but maybe you can use the same code as above with a few changes:
$fn = $_FILES["upload"]["name"]; // name of file have some utf-8 characters
$name=iconv('utf-8','cp936', $fn);
move_uploaded_file($_FILES["upload"]["tmp_name"],$name );
The only solution I have found so far.. (2014 year):
1) I dont store files on my FTP in UTF-8 string. Instead, i use this function, to rename the uploaded files:
<?php
// use your custom function.. for example, utf8_encode
$newname = utf8_encode($_FILES["uploadFile"]["name"]);
move_uploaded_file($_FILES["uploadFile"]["tmp_name"], $newname);
?>
2) Now you can rename (or etc) $newname;
For a start get detecting filename encoding (before uploading).
print_r($_FILES["upload"]);
Insert filename to decoder and check encoding.
Sorry! your question is about file name.
You must save your file name with iconv but read without this.
for saving:
<?php
$name = $_FILES['photo']['name'];
$unicode = iconv('windows-1256', 'utf-8', $name);
move_uploaded_file($_FILES['photo']['tmp_name'], 'photos/' . $name);
mysql_query("INSERT INTO `photos` (`filename`) VALUES ('{$unicode}')");
?>
for reading:
<?php
$images = mysql_query('SELECT * FROM `photos`');
if($images && mysql_num_rows($images) > 0) {
while($image = mysql_fetch_assoc($images)) {
$name = iconv('utf-8', 'windows-1256', $image['filename']);
echo '<img src="photos/' . $name . '"/>';
}
mysql_free_result($images);
}?>
function convToUtf8($str)
{
if( mb_detect_encoding($str,"UTF-8, ISO-8859-1, GBK")!="UTF-8" )
{
return iconv("gbk","utf-8",$str);
}
else
{
return $str;
}
}
$filename= convToUtf8($filename) ;
try this
$imgname = $_FILES['img'] ['name'] ;
$imgsize = $_FILES['img'] ['size'] ;
$imgtmpname = $_FILES['img'] ['tmp_name'] ;
$imgtype = $_FILES['img'] ['type'] ;
$size = 1024;
$imgtypes = array('image/jpeg','image/gif','image/png');
$folder = "up";
if(empty($imgname)){
echo "Shose ur photo";
}else if(!in_array($imgtype,$imgtypes)){
echo "this photo type is not avalable";
}else if($imgsize > $size){
echo "this photo is dig than 6 MB";
}else if($imgwidth > 5000){
echo "the file is to big";
}
else{
move_uploaded_file($imgtmpname, $folder, $filename);
}
You can use this
$fn2 = basename($_FILES['upload']['name']);
Here is my working code:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/>
</head>
<body>
<?php
$arabic = "صحيفة اسبوعية مستقلة شاملة تتابع الاخبار فى المنطقة العربية";
$french = "que voulez vous dire?";
if (isset($_POST['search'])) {
$search = $_POST['search'];
$key = $_POST['key'];
$td = substr_count($arabic, $key);
echo $td;
}
echo "<br />" . $arabic;
function count_occurences($char_string, $haystack, $case_sensitive = true) {
if ($case_sensitive === false) {
$char_string = strtolower($char_string);
$haystack = strtolower($haystack);
}
$characters = preg_split('//u', $char_string, -1, PREG_SPLIT_NO_EMPTY);
//$characters = str_split($char_string);
$character_count = 0;
foreach ($characters as $character) {
$character_count = $character_count + substr_count($haystack, $character);
}
return $character_count;
}
?>
<form name="input" action="" method="post">
<input type= "text" name="key" value=""/>
<input type ="submit" name="search" value =" find it !"/>
</form>
</body>
</html>
For the $french it works good, however with $arabic it doesn't.
Of course there is no error but if I enter for example ح to search for that letter, it shows always 0 for every letter I enter.
Is there some wrong? Or am I missing something with Arabic? I don't know why in $french works good if i enter v it shows 2 in result.
You need to use Multibyte String Functions.
You can also set mbstring.func_overload = 7 in your php.ini, and php will automatically use multibyte counterparts for standard string functions.
Look at mbstring overloading documentation if you want to use some other value for overloaded functions which would suit your needs better
Also, replace
$characters = str_split($char_string);
with
$characters = preg_split('//u', $char_string, -1, PREG_SPLIT_NO_EMPTY);
because str_split is not multibyte safe and has no alternative
Additionaly, if no encoding is sent in the headers after you submit the form, or there is some issue with them, you can set in your php.ini
default_charset = "UTF-8"
i tested your code with Encoding UTF-8, and it's work..
i'v added a meta tag:
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
So I downloaded and edited a script off the internet to pull an image and find out the hex values it contains and their percentages:
The script is here:
<?php
$delta = 5;
$reduce_brightness = true;
$reduce_gradients = true;
$num_results = 5;
include_once("colors.inc.php");
$ex=new GetMostCommonColors();
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>Colour Verification</title>
</head>
<body>
<div id="wrap">
<img src="http://www.image.come/image.png" alt="test image" />
<?php
$colors=$ex->Get_Color("http://www.image.come/image.png", $num_results, $reduce_brightness, $reduce_gradients, $delta);
$success = true;
foreach ( $colors as $hex => $count ) {
if ($hex !== 'e6af23') {$success = false; }
if ($hex == 'e6af23' && $count > 0.05) {$success = true; break;}
}
if ($success == true) { echo "This is the correct colour. Success!"; } else { echo "This is NOT the correct colour. Failure!"; }
?>
</div>
</body>
</html>
Here is a pastebin link to the file colors.inc.php
http://pastebin.com/phUe5Pad
Now the script works absolutely fine if I use an image that is on the server, eg use /image.png in the Get_Color function. However, if I try and use an image from another website including a http://www.site.com/image.png then the script no longer works and this error appears:
Warning: Invalid argument supplied for foreach() in ... on line 22
Is anyone able to see a way that I would be able to hotlink to images because this was the whole point of using the script!
You must download a file to the server and pass its full filename to the method Get_Color($img) as $img parameter.
So, you need to investigate another SO question: Download File to server from URL
The error indicates that the value returned by Get_Color is not a valid object that can be iterated on, probably not a collection. You need to know how the Get_Color works internally and what is returned when it doesn't get what it wants.
In the mean-time, you can download [with PHP] the image from the external url into your site, and into the required folder and read the image from there.
$image = "http://www.image.come/image.png";
download($image, 'folderName'); //your custom function
dnld_image_name = getNameOfImage();
$colors=$ex->Get_Color("/foldername/dnld_image_name.png");
By the way, did you confirm that the image url was correct?
I am hoping to offer users a user submitted image gallery. I have written a upload script which saves the file above the www root. I know I can serve the file by specifying the page header and then using readfile, however I am planning to throw the images within a table to be displayed with other information and dont think the header/readfile is the best solution. I am thinking maybe symlinks but I am not sure.
What is the best method to achieve this?
You'll need a script like getimage.php which sends the image headers and echo's out its contents. Then in your HTML, you just utilize it as the <img src=''> in your HTML. The only purpose of getimage.php is to retrieve and output the image. It remains separate from whatever PHP you use to generate the HTML sent to the browser.
Additionally, you can check if the user has a valid session and permission to view the image in getimage.php and if not, send a some kind of access-denied image instead.
The contents of getimage.php are small and simple:
// Check user permissions if necessary...
// Retrieve your image from $_GET['imgId'] however appropriate to your file structure
// Whatever is necessary to determine the image file path from the imgId parameter.
// Output the image.
$img = file_get_contents("/path/to/image.jpg");
header("Content-type: image/jpeg");
echo($img);
exit();
In your HTML:
<!-- as many as you need -->
<img src='getimage.php?imgId=12345' />
<img src='getimage.php?imgId=23456' />
<img src='getimage.php?imgId=34567' />
It then becomes the browser's job to call getimage.php?imgId=12345 as the path to the image. The browser has no idea it is calling a PHP script, rather than an image in a web accessible directory.
If the script is running on a Unix server, you might try to create a symlink in your web root that links to the directory outside of your web root.
ln -s /webroot/pictures /outside-of-webroot/uploads
If you're using an Apache server you could also have a look at mod_alias.
I've heard that there are a few issues when using mod_alias and configuring it through .htaccess. Unfortunately I don't have any experience with mod_alias whatsoever.
Something that always has worked well for me is to have users upload their images directly into my mysql db. The PHP will encode into base64 and store into a blob. Then you do something similar to what michael said to retrieve and display the image. I've included some code from a project I was working on in 2008. I wouldn't copy it exactly if it's a method you're interested in using since it's old code.
This is the PHP to upload and store into a DB. Obviously replace your info and connect to your own DB.
<?php
include("auth.php");
// uploadimg.php
// By Tyler Biscoe
// 09 Mar 2008
// Test file for image uploads
include("connect.php");
include("include/header.php");
$max_file_size = 786432;
$max_kb = $max_file_size/1024;
if($_POST["imgsubmit"])
{
if($_FILES["file"]["size"] > $max_file_size)
{
$error = "Error: File size must be under ". $max_kb . " kb.";
}
if (!($_FILES["file"]["type"] == "image/gif") && !($_FILES["file"]["type"] == "image/jpeg") && !($_FILES["file"]["type"] == "image/pjpeg"))
{
$error .= "Error: Invalid file type. Use gif or jpg files only.";
}
if(!$error)
{
echo "<div id='alertBox'> Image has been successfully uploaded! </div>";
$handle = fopen($_FILES["file"]["tmp_name"],'r');
$file_content = fread($handle,$_FILES["file"]["size"]);
fclose($handle);
$encoded = chunk_split(base64_encode($file_content));
$id = $_POST["userid"];
echo $_FILES["file"]["tmp_name"];
$default_exist_sql = "SELECT * FROM members WHERE id='".$id."'";
$default_result = mysql_query($default_exist_sql);
$results = mysql_fetch_array($default_result);
if(!$results["default_image"])
{
$insert_sql = "UPDATE members SET default_image = '$encoded' WHERE id='". $id ."'";
mysql_query($insert_sql);
}
$sql = "INSERT INTO images (userid, sixfourdata) VALUES ('$id','$encoded')";
mysql_query($sql);
}
else
{
echo "<div id='alertBox'>". $error . "</div>";
}
}
?>
<br />
<font class="heading"> Upload images </font>
<br /><br />
<form enctype = "multipart/form-data" action = "<?php $_SERVER['PHP_SELF']; ?>" method = "post" name = "uploadImage">
<input type = "hidden" name="userid" value = "<?php echo $_GET["userid"]; ?>" >
<input id="stextBox" type="file" name="file" size="35"><br />
<input type="submit" name="imgsubmit" value="Upload">
</form>
<?php include("include/footer.php"); ?>
This next one displays the file:
<?php
// image.php
// By Tyler Biscoe
// 09 Mar 2008
// File used to display pictures
include("connect.php");
$imgid = $_GET["id"];
$result = mysql_query("SELECT * FROM images WHERE imgid=" . $imgid . "");
$image = mysql_fetch_array($result);
echo base64_decode($image["sixfourdata"]);
echo $image["sixfourdata"];
?>
Then:
<img src="image.php?id=your_img_id">