I've got a site where the user can upload a csv file with some information and I read and save that information in the database. The problem is, the user sometimes report that the information he/she uploads appears with "strange characters" in the browser and I've checked and it was saved in the database the same way (with "strange characters). So I asked for the file he/she used and upload from my computer and everything went fine. The user uploaded from a Mac computer and I uploaded from a Windows computer. The server with the site is Windows.
Here's a print of the error the user describes:
I can upload that same csv and that string stays ok. I noticed the "strange characters" are codes for url's. For example the space is replaced by %20 in the print. But this string comes from a csv file that apparently is ok. And as I can't reproduce the error it's hard to understand what could be happening. But all seems to be some kind of encoding problem between Mac-Windows. Do you ever got this king of problem?
EDIT:
Here's the code that handles the csv file:
while ($valor = fgetcsv ($handle, filesize($T2), ";")){
for ($i=0;$i<$conta;$i++){
$cv=$data[$i];
$row[$cv]=trim($valor[$i]);
}
if ($row['Ano']==$sql_Documento['Ano'] && $sql_Documento['NumDocumento']==$row['Numero']){
$count++;
$campos = array();
$campos['IdDocumento'] = $sql_Documento[IdDocumento];
$campos['Sociedade'] = mssql_escape_string($row['Sociedade']); //this is the field that gives me problems
$campos['DocumentoId'] = $sql_Documento[DocumentoId];
$campos['page_dr'] = $row['Pagdr'];
$campos['page_file'] = $row['Pagpdf'];
$DocumentoId = insertNewRecord("DocSoc",$campos);
}
}
The mssql_escape_string is this function:
function mssql_escape_string($data) {
if ( !isset($data) or empty($data) ) return '';
if ( is_numeric($data) ) return $data;
$non_displayables = array(
'/%0[0-8bcef]/', // url encoded 00-08, 11, 12, 14, 15
'/%1[0-9a-f]/', // url encoded 16-31
'/[\x00-\x08]/', // 00-08
'/\x0b/', // 11
'/\x0c/', // 12
'/[\x0e-\x1f]/' // 14-31
);
foreach ( $non_displayables as $regex )
$data = preg_replace( $regex, '', $data );
$data = str_replace("'", "''", $data );
return $data;
}
Related
I know there are a lot of similar question has already been asked in this community but unfortunately nothing gonna work for me.
I have a CSV sheet which I need to import in our system. Sheet is getting imported without any issue in Linux (creating the sheet with Libre Office) even with Irish character.
But main problem starts in Windows and iOS environment with excel (MS-excel) where character encoding get changed. And few of the Irish characters like
Ž, Ŕ and many others are getting changed to different symbols.
P.S : CSV is working fine if we are creating that through Numbers in iOS.
Below is the php method by which I'm reading the CSV sheet.
$path = CUploadedFile::getInstance($model, 'absence_data_file'); // Get the instance of selected file
$target = ['First Name', 'Last Name', 'Class', 'Year', 'From']; // Valid Header
public static function readCSV($path, $target) {
$updated_header = array();
$data = array();
if ($path->type == 'text/csv' || $path->type == 'application/vnd.ms-excel' || $path->type == 'text/plain' || $path->type == 'text/tsv') {
$fp = fopen($path->tempName, 'r');
$encoding_type = mb_detect_encoding(file_get_contents($path->tempName));
if ($fp !== FALSE) {
$header = fgetcsv($fp);
foreach ($header as $h) {
$updated_header[] = $h;
}
$updated_header = array_map( 'trim', array_values($updated_header));
if (array_diff($target, $updated_header)) {
$errormessage = 'Invalid header format.';
return $errormessage;
} else {
while ($ar = fgetcsv($fp)) {
$data[] = array_combine($updated_header, $ar);
}
$data['file_encoding'] = $encoding_type;
return $data;
}
}
} else {
$errormessage = "Invalid File type, You can import CSV files only";
return $errormessage;
}
}
Sheet which I'm importing (Check the pic):
Printing the data (First Record)
I'm not sure about Irish Codepage, but if it is Western European as you mentioned in your comment, I'm guessing your codepage would be ISO-8859-1 or ISO-8859-14, and your line of code should be:
$encoding_type = mb_detect_encoding(file_get_contents($path->tempName), 'ISO-8859-1', true);
or just simply following since you are sure its encoding is 'ISO-8859-1'
$encoding_type = 'ISO-8859-1'
Second and 3rd parameters in mb_detect_encoding tells the function to strictly try and encode using ISO-8859-1 if you want to try other codepages at the same time, you can provide a list of comma separated code pages to second parameter, e.g. UTF-8, ISO-8859-1
Note that you will need to call mb_convert_encoding to actually get the file in your desired encoding, so following code will strictly try to decode from ISO-8859-1 to UTF-8
$UTF8_text = mb_convert_encoding($content, 'UTF-8', 'ISO-8859-1');
if you insist in using fgetcsv, have a look at (mb_internal_encoding)[https://www.php.net/manual/en/function.mb-internal-encoding.php], it will set default encoding.
I'm using this jquery plugin to capture or draw a signature.
http://keith-wood.name/signature.html
And FPDF php plugin to generate pdf
Now I must include signature into pdf...
With FPDF I can insert an image, but I have problem exporting signature to jpeg/png (I don't even know if is possibile)
How I can do this
On the page you gave link to (this one) in Save/Restore tab you have possibility to save it as a base64 encoded picture (jpeg or png).
So you can use that and to save base64 encoded picture as a file here is a solution
The problem is that data:image/png;base64, is included in the encoded contents. This will result in invalid image data when the base64 function decodes it. Remove that data in the function before decoding the string, like so.
function base64_to_jpeg($base64_string, $output_file) {
// open the output file for writing
$ifp = fopen( $output_file, 'wb' );
// split the string on commas
// $data[ 0 ] == "data:image/png;base64"
// $data[ 1 ] == <actual base64 string>
$data = explode( ',', $base64_string );
// we could add validation here with ensuring count( $data ) > 1
fwrite( $ifp, base64_decode( $data[ 1 ] ) );
// clean up the file resource
fclose( $ifp );
return $output_file;
}
To clarify variable $base64string is a string that in your case is generated by plugin, and $output_file is a filpath where to save the picture.
I update information on data.csv using:
function generateCsv($data, $delimiter = ',', $enclosure = '"') {
$dataPath = $_SERVER["DOCUMENT_ROOT"] .'/test-los-goya-2015/alfombra-roja/data.csv';
$handle = fopen($dataPath, 'r+');
#ftruncate($handle, 0);
foreach ($data as $line) {
fputcsv($handle, $line, $delimiter, $enclosure);
}
fclose($handle);
And then, when the user clicks on the Publish button, I do:
function publishCsv () {
$dataPath = $_SERVER["DOCUMENT_ROOT"] .'/test-los-goya-2015/alfombra-roja/data.csv';
$dataPublishedPath = $_SERVER["DOCUMENT_ROOT"] .'/test-los-goya-2015/alfombra-roja/data-published.csv';
copy($dataPath, $dataPublishedPath);
}
And then the information is visible right away on front. However, the updated information on data.csv is not visible on backoffice until about 10 minutes have passed.
We are using Level 3 CDN which holds strong caching, however, the information retrieval is always done to http://origin-...., like this piece of code I have when I read information from data.csv (backoffice) and data-published.csv (front):
if (!$getPublished) {
$dataPath = 'http://origin-lab.rtve.es/test-los-goya-2015/alfombra-roja/data.csv';
} else {
$dataPath = 'http://origin-lab.rtve.es/test-los-goya-2015/alfombra-roja/data-published.csv';
}
$aLines = file( $dataPath );
How is it possible that getting the information from the csv files, being exactly the same way, shows updated information on the front, but not on backoffice?
Thanks a lot
I am using a script to send a "$filename" variable from flash to PHP in order to create an xml file. The problem is that when I am typing Greek Characters as Filename the filename on the server gets values such as these for example: (δσωδσαωςεωςεβ.qxml)
I do not have any problem a) When writing english characters, b) When writing greek characters data in the xml file.
I am using file_put_contents function.
If instead of getting the Post variable as filename, I set my own filename such as "Ελληνικά.qxml" it works without a problem.
Thanks a lot in advance.
$string = $_POST['xmldata'];
$filename = $_POST['filename'];
$path = "test/";
//$dir_handle = #opendir($path) or mkdir("{$path}", 0777, true);
file_put_contents($path."/".$filename."", $string);
This problem was solved, but another arose. When I try to open the file from flash it does not recognise it now because it is in Greek.
The problem is that flash is sending the data in different encoding. From the comments in the PHP manual for mb_convert_encoding I can see that you should use the following to get it to work (tested on danisch charactors and not greek)
<?php
$string = isset($_POST['xmldata'])?$_POST['xmldata']:"";
$filename = isset($_POST['filename'])?$_POST['filename']:"";
//tested on danish chars
/*
$string = mb_convert_encoding($string, "ISO-8859-1", "UTF-8");
$filename = mb_convert_encoding($filename, "ISO-8859-1", "UTF-8");
*/
//tested on greek chars
$string = mb_convert_encoding($string, "ISO-8859-7", "UTF-8");
$filename = mb_convert_encoding($filename, "ISO-8859-7", "UTF-8");
$path = "test/";
//$dir_handle = #opendir($path) or mkdir("{$path}", 0777, true);
file_put_contents($path."/".$filename."", $string);
?>
Using PHP 5.3 fgetcsv function, I am experiencing some problems due to encoding matters. Note that that file has spanish "special" latin characters like graphic accents á, é, í ï, etc...
I get the CSV file exporting some structured data I have in an MS 2008 for Mac Excel file.
If I open it with Mac OS X TextEdit application, everything seems to go perfect.
But when I get down to my PHP program and try to read the CSV using that fgetcsv PHP function, I am not getting it to read properly the charset.
/**
* #Route("/cvsLoad", name="_csv_load")
* #Template()
*/
public function cvsLoadAction(){
//setlocale(LC_ALL, 'es_ES.UTF-8');
$reader = new Reader($this->get('kernel')->getRootDir().'/../web/uploads/documents/question_images/2/41/masiva.csv');
$i = 1;
$r = array("hhh" => $reader -> getAll());
return new Response(json_encode($r, 200));
}
As you can see, I have tried also to use a setlocale to es_ES.UTF-8. But nothing get it working.
The read part comes here:
public function getRow()
{
if (($row = fgetcsv($this->_handle, 10000, $this->_delimiter)) !== false) {
$this->_line++;
return $this->_headers ? array_combine($this->_headers, $row) : $row;
} else {
return false;
}
}
See what I get in the $row variable after each row reading:
Those ? characters are supposed to be vowels with graphic accents on them.
Any clue over there? Would it work if I used MS Excel for Windows? How can I know in run time the exact encoding of the file and set it before reading it?
(For those spanish speakers, don't get frightened with such awful medical stuff in those texts ;)).
Try this:
function convert( $str ) {
return iconv( "Windows-1252", "UTF-8", $str );
}
public function getRow()
{
if (($row = fgetcsv($this->_handle, 10000, $this->_delimiter)) !== false) {
$row = array_map( "convert", $row );
$this->_line++;
return $this->_headers ? array_combine($this->_headers, $row) : $row;
} else {
return false;
}
}
This is likely to do with the way excel encodes the file when saving.
Try uploading the .xls file to google docs and downloading as a .csv