0

I been trying to unset a value from an array without success, I'm trying to be able to edit values from a CSV file. When I click edit it should open the values load it locally unset it and re save the array with the new value. My problem is that the all the values are being added twice along with the new edit value.

This is my edit function

class edit extends index{ public function GET(){ $Remail = ($_REQUEST['email']); $filename = 'testfile.csv'; $lines = file($filename); foreach($lines as $info) { $CSVString = explode(',', $info); $this->email = trim(explode("=", $CSVString[0])[1]); if ($Remail === $this->email){ $this->Fname = trim(explode("=", $CSVString[1])[1]); $this->Lname = trim(explode("=", $CSVString[2])[1]); unset($CSVString[0]); } $this->person = array('Email'=>$this->email,'FirstName' =>$this- >Fname, 'LastName' =>$this->Lname); $this->save($this->person); } echo '<form action="index.php?page=adduser" method="POST"> <label for="email">Email:</label></br> <input type="text" name="Email" value="' . $Remail . '"></br> <label for="fname">First Name:</label></br> <input type="text" name="Fname" value="' . $this->Fname . '"></br> <label for="lname">Last Name:</label></br> <input type="text" name="Lname" value="' . $this->Lname . '"></br> <input type="submit"> </form>'; } 

this is my save function

public function save($arr){ $filename = 'testfile.csv'; $myfile = fopen($filename, "a+") or die("Unable to open file!"); foreach($arr as $key => $value){ $new [] = $key.'='.$value; $final = implode(",", $new); } fwrite($myfile, $final.PHP_EOL); fclose($myfile); } 

And this is the adduser that the form is calling

class adduser extends index { public function GET(){ include('add.html'); } public function POST($Fname, $Lname, $Email){ $this->Fname = $Fname; $this->Lname = $Lname; $this->Email = $Email; $this->person = array('Email'=>$this->Email,'FirstName' =>$this->Fname, 'LastName' =>$this->Lname); $this->save($this->person); 

1 Answer 1

1

Let's say you visit index.php?page=edit&[email protected]. I understand you then want to consult your CSV file and pull up this user's data and display their first and last name in a form you can edit and submit. The problem, however, is that you're submitting to index.php?page=adduser which adds the user, not edit it. I see you have two classes edit and adduser. Just as your adduser class has a GET() and POST() method, you should also have a GET() and POST() method for your edit class. The reason you're seeing duplicate data is because your edit class's GET() method is actually calling save() when there's no data to be saving in the first place. And it won't edit the data either, it will reference your $this->Fname and $this->Lname for each loop, which I assume is not set in the first place. Thus you end up appending a bunch of rows to your CSV file with the correct emails but with the same FirstName and LastName for each row, thus corrupting your data.

In terms of a solution here, simply don't call $this->save($this->person); from your edit's GET() method. Update the form to submit to the correct page:
<form action="index.php?page=edit" method="POST">
Also add a reference to the user's email as a hidden field under a different key, in case the user wants to change their email:
echo '<input type="hidden" name="oldemail" value="'.htmlentities($Remail).'">';
(yes, make sure to always escape the user's input when displaying it in HTML)

Then create a new POST() method in your edit class with the logic:

public function POST($p_oldEmail, $p_Fname, $p_Lname, $p_Email) { $filename = 'testfile.csv'; $lines = file($filename) or die("Unable to open file!");; $out = ''; foreach($lines as $info) { $fields = explode(',', $info); $email=trim(explode("=", $fields[0])[1]); if($email === $p_oldEmail) { $record=array('Email'=>$p_Email,'FirstName'=>$p_Fname, 'LastName'=>$p_Lname); $new=array(); foreach($record as $key => $value) { $new[] = $key.'='.$value; } $out.=implode(",", $new).PHP_EOL; }else{ $out.=$info; } } $myfile = fopen($filename, "w") or die("Unable to open file!"); fwrite($myfile, $out); fclose($myfile); } 

(Note that the above is untested, you may have to make a slight adjustment to it)

In the future, I'd advise using fgetcsv() for parsing a CSV file one line at a time or str_getcsv for parsing an entire CSV file represented as a string in one chuck. And fputcsv for writing a line to a CSV file. Using these functions ensures proper escaping so your CSV file doesn't get corrupted if someone enters unexpected input. Although if someone enters a new line into a field, even if escaped properly, if you're reading your CSV file line by line, regardless of the new line being between quotes, then you'll run into an issue with PHP-designed functions which read a file one line at a time without caring if that line is between quotes. So if you need to preserve new lines which users might enter, I'd suggest converting them to their HTML entity equivalents when storing them in the CSV file. But if you are serious about these kind of things, you should really be using a database rather than a CSV file.

Sign up to request clarification or add additional context in comments.

4 Comments

The professor wanted us to start of with CSV files, later on we moving into mysql. And im gettig this error Warning: Missing argument 4 for edit::POST(), called in /var/www/html/index.php on line 19 and defined in /var/www/html/controllers/edit.php on line 6 Notice: Undefined index: email in /var/www/html/controllers/edit.php on line 38 Notice: Undefined property: edit::$Fname in /var/www/html/controllers/edit.php on line 63 Notice: Undefined property: edit::$Lname in /var/www/html/controllers/edit.php on line 65 Email:
You're calling my function wrong. It requires 4 arguments, as your error says. My function expects the first argument to be $_POST['oldemail']. The other three being $_POST['fname'], $_POST['lname'], $_POST['email']. I thought that would be clear from the p_ prefixes of my variables. My code also makes no reference to the $this->Fname or $this->Lname properties in the first place. If you're getting errors regarding these properties, which my code doesn't use, then your error is elsewhere in code you haven't shown us yet.
Got that part working, now my last part is deleting the user. based on email parameter. I noticed that my server doesn't support DELETE nor PUT methods just GET and POST. I need to add the delete button on the edit form.
You could do something like <button type="submit" name="act" value="edit">Submit Changes</button><button type="submit" name="act" value="delete">Delete</button> then check for which button was clicked with if($_POST['act']=='edit'){...}elseif($_POST['act']=='delete'){...} some people prefer just putting a checkbox in the form though and if it's checked then treat the edit request as a delete request.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.