I was working on the eCommerce site and uploading the CSV file in the PHP database of Size that having the comma. The outcome of the result is the database is coming up with backward slash and double-quotes.
Please help me in rectifying that issue as had wasted my two days working on it.
CSV Format in notepad
Product Name,Footware Size
Shirt,"""35,36,34"""
Image of my csv file
CSV File
But it saved in the table
Table Screenshot
Code OF upload CSV File into the database
if($_FILES['csv_file']['name'])
{
$filename = explode(".", $_FILES['csv_file']['name']);
if(end($filename) == "csv")
{
$handle = fopen($_FILES['csv_file']['tmp_name'], "r");
$find_header = 0;
while($data = fgetcsv($handle,6000,",",'"'))
{
$find_header++;
if($find_header > 1){
$name = $database->escape_string($data[0]);
$foot_size = trim(addslashes($data[2]), '"');;
$products = new Product();
$products->product_name = $name;
$products->created_at = $time;
$products->updated_at = $time;
$result = $products->save();
if($result){
$product_id = $products->id;
if(!empty($foot_size)){
$sizes = explode(',', $foot_size);
$size_str = '';
foreach($sizes as $size){
$size_str .= $size.',';
}
$p_size = rtrim($size_str,",");
$product_size = new FootSize();
$product_size->product_id = $product_id;
$product_size->foot_size = $p_size;
$product_size->date = $time;
$product_size->save();
}
}
}
}
if($result === true){
$session->message('Product File Uploaded Successfully.');
fclose($handle);
redirect_to('add_product_csv');
}
}
else
{
$message = '<label class="text-danger">Please Select CSV File only</label>';
}
}
Problem
You have an error in this line:
$foot_size = trim(addslashes($data[2]), '"');
What it does is to first escape double quotes:
"35,36,34" --> \"35,36,34\"
And then trim them:
\"35,36,34\" --> \"35,36,34\
Solution
Depending on if you actually want to have the quotes stored in your DB or not, call either trim or addslahes (but not both) or none of the two:
Strip quotes:
$foot_size = trim($data[2], '"');
Keep quotes:
$foot_size = $data[2];
# your framework *might* require explicitly escaping of quote chars:
$foot_size = addslashes($data[2]);
# even better:
$foot_size = $database->escape_string($data[2]);
Related
I'm trying to get an image from an E-mail which is sent to my mailserver and save the file to the server. I tried it with this code:
$no_of_occurences = 0;
$intStatic = 2;
$decode = imap_fetchbody($mbox, $val , null);
$no_of_occurences = substr_count($decode,"Content-Transfer-Encoding: base64");
$no_of_occurences--;
echo $no_of_occurences;
if($no_of_occurences > 0){
for($i = 0; $i < $no_of_occurences; $i++){
$strChange = strval($intStatic+$i);
$decode = imap_fetchbody($mbox, $val , $strChange);
$data = base64_decode($decode);
$x = 1;
$fName = './images/'.$ticketurl."_".$x. '.png';
while(file_exists($fName)){
$x++;
$fName = './images/'.$ticketurl."_".$x. '.png';
}
if($x==500){
$valid = false;
exit;
}
$file = $fName;
$success = file_put_contents($file, $data);
}
}
This code is working fine but only if you have one type of appendage in it. If you place one image inline the mail it is working. If you place one as an attachment, it also works. But if you got both (inline and as attachment) it's just getting one image and a second clean png file.
Any suggestions how to solve this behavior?
So I am storing my files in a database. Don't ask why, just know that I am not in control of this. Next, I am able to successfully store them as a hexidecimal representation and then spit them back for display with no problem, but then I attach them to an email using PHPMailer and they get sent properly with the right name and all, but they are corrupted. I will walk you through step by step below so that you know exactly how it is being stored, and this may help me debug my issue. (Please note that all code is paraphrased to save space and only show what is needed)
STEP 1
File is grabbed and then processed
$name = $_FILES['file_data']['name'];
$file = prepareImageDBString($_FILES['file_data']['tmp_name']);
$mime_type = $_FILES['file_data']['type'];
name, file, and mime_type are stored
here is the function prepareImageDBString()
function prepareImageDBString($filepath){
$out = 'null';
$handle = #fopen($filepath, 'r');
if($handle){
$content = #fread($handle, filesize($filepath));
$content = bin2hex($content);
#fclose($handle);
$out = $content;
}
return $out;
}
STEP 2
When the file is being viewed I show it as an embedded object. This file is small so I just posted the whole code. Do note that the file shows up with no problems here.
$q = "SELECT lease_doc_file_data FROM lease_doc_file WHERE lease_doc__id ='".$_GET['id']."'";
$file = "";
foreach($CONN->query($q) as $row){
$file = $row['lease_doc_file_data'];
}
if(!empty($file)){
header("Content-type: application/pdf");
ob_clean();
flush();
echo hextobin($file);
}
Here is the function hextobin()
function hextobin($hexstr){
$n = strlen($hexstr);
$sbin = "";
$i = 0;
while($i < $n){
$a = substr($hexstr,$i,2);
$c = pack("H*", $a);
if ( $i == 0 ){ $sbin = $c; }
else { $sbin .= $c;}
$i += 2;
}
return $sbin;
}
STEP 3
Finally the part where I go to send it as a mailer.
$q = "SELECT lease_doc_file_data, lease_doc_file_name, lease_doc_file_type FROM lease_doc_file WHERE lease_doc__id ='$id'";
$file_data = "";
$file_name = "";
$file_type = "";
foreach($CONN->query($q) as $row){
$file_data = $row['lease_doc_file_data'];
$file_name = $row['lease_doc_file_name'];
$file_type = $row['lease_doc_file_type'];
}
$file_data = hextobin($file_data);
$mail->AddStringAttachment($file_data, $file_name, 'binary', $file_type);
So this is the three step process and I"m not sure where the error is coming from. Hopefully someone can help! Thank you for all help in advance!
I want to parse very large csv into mysql using php. My idea is to make it with executing 4-5 times the request which will paste data into mysql, after each iteration request should start from rows which has not been pasted yet (with one request iteration script can cover 400 rows). But I don't know to skip rows in csv, which has been already pasted into database. Maybe I should check number of rows in the table then define some variable with this number and make iteration according on it. But I don't know how to operate with csv using foreach, I only have code with "while" from example.
Here is my current code:
public function action_index(){
if(($handle = fopen('data_wpic.csv', 'r')) !== false)
{
$header = fgetcsv($handle);
while(($data = fgetcsv($handle)) !== false)
{
$model = ORM::factory('Drug');
$image_path = $data[18];
if(strlen($image_path) > 5) {
$path= 'drug_images/' . $image_path;
$image = ORM::factory('Image')->remote($path);
if ($image) {
$model->image_id = $image;
unlink($path);
}
}
$model->drugGenericName = $data[17];
$model->drugForm = $data[4];
$model->drugProperties = $data[7];
$model->drugIndication = $data[2];
$model->drugDosage = $data[13];
$model->drugSide = $data[11];
$model->drugContrIndication = $data[12];
$model->drugInteractions = $data[15];
$model->drugSpecial = $data[0];
$model->drugExpiry = $data[3];
$model->drugRealCondition = $data[8];
$model->tradeName = $data[16];
$model->save();
unset($data);
}
fclose($handle);
}
}
I have limited web hosting, thats why I try to solve this routine
If someone knows better aproach - I will be glad to hear him
I need a script that is finding and then replacing a sertain line in a CSV like file.
The file looks like this:
18:110327,98414,127500,114185,121701,89379,89385,89382,92223,89388,89366,89362,89372,89369
21:82297,79292,89359,89382,83486,99100
98:110327,98414,127500,114185,121701
24:82297,79292,89359,89382,83486,99100
Now i need to change the line 21.
This is wat i got so far.
The first 2 to 4 digits folowed by : ar a catergory number. Every number after this(followed by a ,) is a id of a page.
I acces te id's i want (i.e. 82297 and so on) from database.
//test 2
$sQry = "SELECT * FROM artikelen WHERE adviesprijs <>''";
$rQuery = mysql_query ($sQry);
if ( $rQuery === false )
{
echo mysql_error ();
exit ;
}
$aResult = array ();
while ( $r = mysql_fetch_assoc ($rQuery) )
{
$aResult[] = $r['artikelid'];
}
$replace_val_dirty = join(",",$aResult);
$replace_val= "21:".$replace_val_dirty;
// file location
$file='../../data/articles/index.lst';
// read the file index.lst
$file1 = file_get_contents($file);
//strip eerde artikel id van index.lst
$file3='../../data/articles/index_grp21.lst';
$file3_contents = file_get_contents($file3);
$file2 = str_replace($file3_contents, $replace_val, $file1);
if (file_exists($file)) {
echo "The file $filename exists";
} else {
echo "The file $filename does not exist";
}
if (file_exists($file3)) {
echo "The file $filename exists";
} else {
echo "The file $filename does not exist";
}
// replace the data
$file_val = $file2;
// write the file
file_put_contents($file, $file_val);
//write index_grp98.lst
file_put_contents($file3, $replace_val);
mail('info#', 'Aanbieding catergorie geupdate', 'Aanbieding catergorie geupdate');
Can anyone point me in the right direction to do this?
Any help would be appreciated.
You need to open the original file and go through each line. When you find the line to be changed, change that line.
As you can not edit the file while you do that, you write a temporary file while doing this, so you copy over line-by-line and in case the line needs a change, you change that line.
When you're done with the whole file, you copy over the temporary file to the original file.
Example Code:
$path = 'file';
$category = 21;
$articles = [111182297, 79292, 89359, 89382, 83486, 99100];
$prefix = $category . ':';
$prefixLen = strlen($prefix);
$newLine = $prefix . implode(',', $articles);
This part is just setting up the basics: The category, the IDs of the articles and then building the related strings.
Now opening the file to change the line in:
$file = new SplFileObject($path, 'r+');
$file->setFlags(SplFileObject::DROP_NEW_LINE | SplFileObject::SKIP_EMPTY);
$file->flock(LOCK_EX);
The file is locked so that no other process can edit the file while it gets changed. Next to that file, the temporary file is needed, too:
$temp = new SplTempFileObject(4096);
After setting up the two files, let's go over each line in $file and compare if it needs to be replaced:
foreach ($file as $line) {
$isCategoryLine = substr($line, 0, $prefixLen) === $prefix;
if ($isCategoryLine) {
$line = $newLine;
}
$temp->fwrite($line."\n");
}
Now the $temporary file contains already the changed line. Take note that I used UNIX type of EOF (End Of Line) character (\n), depending on your concrete file-type this may vary.
So now, the temporary file needs to be copied over to the original file. Let's rewind the file, truncate it and then write all lines again:
$file->seek(0);
$file->ftruncate(0);
foreach ($temp as $line) {
$file->fwrite($line);
}
And finally you need to lift the lock:
$file->flock(LOCK_UN);
And that's it, in $file, the line has been replaced.
Example at once:
$path = 'file';
$category = 21;
$articles = [111182297, 79292, 89359, 89382, 83486, 99100];
$prefix = $category . ':';
$prefixLen = strlen($prefix);
$newLine = $prefix . implode(',', $articles);
$file = new SplFileObject($path, 'r+');
$file->setFlags(SplFileObject::DROP_NEW_LINE | SplFileObject::SKIP_EMPTY);
$file->flock(LOCK_EX);
$temp = new SplTempFileObject(4096);
foreach ($file as $line) {
$isCategoryLine = substr($line, 0, $prefixLen) === $prefix;
if ($isCategoryLine) {
$line = $newLine;
}
$temp->fwrite($line."\n");
}
$file->seek(0);
$file->ftruncate(0);
foreach ($temp as $line) {
$file->fwrite($line);
}
$file->flock(LOCK_UN);
Should work with PHP 5.2 and above, I use PHP 5.4 array syntax, you can replace [111182297, ...] with array(111182297, ...) in case you're using PHP 5.2 / 5.3.
I tried and looked for a solution, but cannot find any definitive.
Basically, I have a txt file that lists usernames and passwords. I want to be able to change the password of a certain user.
Contents of users.txt file:
user1,pass1
user2,pass2
user3,pass3
I've tried the following php code:
// $username = look for this user (no help required)
// $userpwd = new password to be set
$myFile = "./users.txt";
$fh = fopen($myFile,'r+');
while(!feof($fh)) {
$users = explode(',',fgets($fh));
if ($users[0] == $username) {
$users[1]=$userpwd;
fwrite($fh,"$users[0],$users[1]");
}
}
fclose($fh);
This should works! :)
$file = "./users.txt";
$fh = fopen($file,'r+');
// string to put username and passwords
$users = '';
while(!feof($fh)) {
$user = explode(',',fgets($fh));
// take-off old "\r\n"
$username = trim($user[0]);
$password = trim($user[1]);
// check for empty indexes
if (!empty($username) AND !empty($password)) {
if ($username == 'mahdi') {
$password = 'okay';
}
$users .= $username . ',' . $password;
$users .= "\r\n";
}
}
// using file_put_contents() instead of fwrite()
file_put_contents('./users.txt', $users);
fclose($fh);
I think when you get that file use file_get_contents after that use preg_replace for the particular user name
I have done this in the past some thing like here
$str = "";
$reorder_file = FILE_PATH;
$filecheck = isFileExists($reorder_file);
if($filecheck != "")
{
$reorder_file = $filecheck;
}
else
{
errorLog("$reorder_file :".FILE_NOT_FOUND);
$error = true;
$reorder_file = "";
}
if($reorder_file!= "")
{
$wishlistbuttonhtml="YOUR PASSWORD WHICH YOU WANT TO REPLACE"
$somecontent = $wishlistbuttonhtml;
$Handle = fopen($reorder_file, 'c+');
$bodytag = file_get_contents($reorder_file);
$str=$bodytag;
$pattern = '/(YOUR_REGEX_WILL_GO_HERE_FOR_REPLACING_PWD)/i';
$replacement = $somecontent;
$content = preg_replace($pattern, $replacement, $str,-1, $count);
fwrite($Handle, $content);
fclose($Handle);
}
Hope this helps....
The proper way of doing this is to use a database instead. Databases can do random access easily, doing it with text files less so.
If you can't switch to a database for whatever reason, and you don't expect to have more than about a thousand users for your system, then it would be far simpler to just read the whole file in, convert it to a PHP data structure, make the changes you need to make, convert it back into text and overwrite the original file.
In this case, that would mean file() to load the text file into an array with each element being a username and password as a string, explode all elements on the array at the comma to get the username and password separately, make the changes you need to make, then write the modified data to disc.
You might also find fgetcsv() useful for reading the data. If you SplFileObject and have a recent version of PHP then fputcsv() may also be available to write the data back out.
However, just using a database is a far better solution. Right tool for the job.
$fn = fopen("test.txt","r") or die("fail to open file");
$fp = fopen('output.txt', 'w') or die('fail to open output file');
while($row = fgets($fn))
{
$num = explode("++", $row);
$name = $num[1];
$sex = $num[2];
$blood = $num[3];
$city = $num[4];
fwrite($fp, "Name: $name\n");
fwrite($fp, "Sex: $sex\n");
fwrite($fp, "Blood: $blood\n");
fwrite($fp, "City: $city\n");
}
fclose($fn);
fclose($fp);
If you're on a *nix system you could use sed; I find it neater than playing with file handles etc:
exec("sed -i '/^$username,.\+\$/$username,$userpwd/g' ./users.txt 2>&1", $output, $return);
If not I'd agree with GordonM and parse the file into a PHP data structure, manipulate it, then put it back:
$data = file_get_contents('./users.txt');
$users = array_map(function($line) {
return explode(',', $line);
}, explode("\n", $data));
foreach ( $users as $i => $user ) {
if ( $user[0] == $username ) {
$user[1] = $userpwd;
$users[$i] = $user;
}
}
file_put_contents('./users.txt', implode("\n", array_map(function($line) {
return implode(',', $line);
}, $users)));
There are, of course, an infinite number of ways of doing that!