Multiple file upload met email verzending
Ik gebruik de folgende functie voor foto winkel waar klanten meerdere foto's kunnen uloaden en die dienen verzonden te worden naar de winkel eigenaar:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
public function upload_fotosAction()
{
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
$vNaam = filter_input(INPUT_POST, 'vNaam', FILTER_SANITIZE_STRING);
$aNaam = filter_input(INPUT_POST, 'aNaam', FILTER_SANITIZE_STRING);
$adres = filter_input(INPUT_POST, 'adres', FILTER_SANITIZE_STRING);
$postcode = filter_input(INPUT_POST, 'postcode', FILTER_SANITIZE_STRING);
$woonplaats = filter_input(INPUT_POST, 'woonplaats', FILTER_SANITIZE_STRING);
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_STRING);
$telefoon = filter_input(INPUT_POST, 'telefoon', FILTER_SANITIZE_STRING);
$uploader_id = $this->page->uploader_toevoegen($vNaam,$aNaam,$adres,$postcode,$woonplaats,$email,$telefoon);
if ($uploader_id)
{
$ontvangers = array(
"[email protected]",
);
$aan = implode(',', $ontvangers);
$onderwerp = 'Afdruk bestelling via de website';
$mail_aanhef = 'De volgende persoon heeft een afdruk bestelling geplaatst';
$naam = $vNaam . ' ' .$aNaam;
$bericht = '';
$bericht .= 'De volgende persoon heeft een afdruk bestelling geplaatst';
$bericht .= "\n\n";
$bericht .= "Naam: ";
$bericht .= $naam;
$bericht .= "\n";
$bericht .= "Adres: ";
$bericht .= $adres;
$bericht .= "\n";
$bericht .= "Woonplaats: ";
$bericht .= $postcode;
$bericht .= "\n";
$bericht .= "Email: ";
$bericht .= $email;
$strSid = md5(uniqid(time()));
$headers = "";
$headers .= "From: [email protected]";
$headers .= "MIME-Version: 1.0\n";
$headers .= "Content-Type: multipart/mixed; boundary=\"".$strSid."\"\n\n";
$headers .= "This is a multi-part message in MIME format.\n";
$headers .= "--".$strSid."\n";
$headers .= "Content-type: text/html; charset=utf-8\n";
$headers .= "Content-Transfer-Encoding: 7bit\n\n";
for($i=0;$i<count($_FILES["file"]["name"]);$i++)
{
if($_FILES["file"]["name"][$i] != "")
{
$filesName = $_FILES["file"]["name"][$i];
$strContent = chunk_split(base64_encode(file_get_contents($_FILES["file"]["tmp_name"][$i])));
$headers .= "--".$strSid."\n";
$headers .= "Content-Type: application/octet-stream; name=\"".$filesName."\"\n";
$headers .= "Content-Transfer-Encoding: base64\n";
$headers .= "Content-Disposition: attachment; filename=\"".$filesName."\"\n\n";
$headers .= $strContent."\n\n";
}
}
$flgSend = mail($aan,$onderwerp,$bericht,$headers);
}
}
}
{
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
$vNaam = filter_input(INPUT_POST, 'vNaam', FILTER_SANITIZE_STRING);
$aNaam = filter_input(INPUT_POST, 'aNaam', FILTER_SANITIZE_STRING);
$adres = filter_input(INPUT_POST, 'adres', FILTER_SANITIZE_STRING);
$postcode = filter_input(INPUT_POST, 'postcode', FILTER_SANITIZE_STRING);
$woonplaats = filter_input(INPUT_POST, 'woonplaats', FILTER_SANITIZE_STRING);
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_STRING);
$telefoon = filter_input(INPUT_POST, 'telefoon', FILTER_SANITIZE_STRING);
$uploader_id = $this->page->uploader_toevoegen($vNaam,$aNaam,$adres,$postcode,$woonplaats,$email,$telefoon);
if ($uploader_id)
{
$ontvangers = array(
"[email protected]",
);
$aan = implode(',', $ontvangers);
$onderwerp = 'Afdruk bestelling via de website';
$mail_aanhef = 'De volgende persoon heeft een afdruk bestelling geplaatst';
$naam = $vNaam . ' ' .$aNaam;
$bericht = '';
$bericht .= 'De volgende persoon heeft een afdruk bestelling geplaatst';
$bericht .= "\n\n";
$bericht .= "Naam: ";
$bericht .= $naam;
$bericht .= "\n";
$bericht .= "Adres: ";
$bericht .= $adres;
$bericht .= "\n";
$bericht .= "Woonplaats: ";
$bericht .= $postcode;
$bericht .= "\n";
$bericht .= "Email: ";
$bericht .= $email;
$strSid = md5(uniqid(time()));
$headers = "";
$headers .= "From: [email protected]";
$headers .= "MIME-Version: 1.0\n";
$headers .= "Content-Type: multipart/mixed; boundary=\"".$strSid."\"\n\n";
$headers .= "This is a multi-part message in MIME format.\n";
$headers .= "--".$strSid."\n";
$headers .= "Content-type: text/html; charset=utf-8\n";
$headers .= "Content-Transfer-Encoding: 7bit\n\n";
for($i=0;$i<count($_FILES["file"]["name"]);$i++)
{
if($_FILES["file"]["name"][$i] != "")
{
$filesName = $_FILES["file"]["name"][$i];
$strContent = chunk_split(base64_encode(file_get_contents($_FILES["file"]["tmp_name"][$i])));
$headers .= "--".$strSid."\n";
$headers .= "Content-Type: application/octet-stream; name=\"".$filesName."\"\n";
$headers .= "Content-Transfer-Encoding: base64\n";
$headers .= "Content-Disposition: attachment; filename=\"".$filesName."\"\n\n";
$headers .= $strContent."\n\n";
}
}
$flgSend = mail($aan,$onderwerp,$bericht,$headers);
}
}
}
Het versturen gaat prima, alleen krijg ik het niet voor elkaar om de bericht gegevens (naam, adres, postcode etc) ook in het bericht te vertonen. Wat doe ik hier fout?
Alvast bedankt
Wat zit er in $vNaam?
Wat geeft een echo $naam op regel 25 (zelf toevoegen dus)?
Hoi Eddy $vNaam is voornaam, $aNaam is achternaam en $naam is dus een combinatie van die twee
Maar, wat geeft een echo daarvan dan? Is die wel gevuld?
if!empty($_POST['vNaam']))
{
$vNaam = $_POST['vNaam'];
echo 'vNaam = '.$_POST['vNaam'];
exit();
}
else
{
echo 'vNaam is leeg.';
exit();
}
Kortom: wat zit er in $vNaam? Is die leeg? Is dat inderdaad de voornaam zoals jij hem ingevuld heb? Is het een "false"?
Hoi Ben, Joni en Eddy. Bedankt voor de reacties. Als ik echo of var_dump gebruik net na $naam geeft het me de juiste waarde! (voor- en achternaam)
Als $vNaam, $aNaam en $naam gewoon waardes hebben is er geen reden dat deze niet in de email terug zouden komen, op basis van deze code.
Netjes met PHPmailer en een nette image upload api
Als je je mail achter elkaar zet dan krijg je nu het volgende:
(eerste de headers...)
multipart/mixed (regel 46)
text/html (regel 49) <-- hier kondig je in feite aan dat de content die volgt HTML is
en nu volgen alle images (regel 52 t/m 64) want deze maken nog deel uit van je headers!
---
(...en dan de body)
hier wordt $bericht afgedrukt, deze bevat geen content type!
Het mag nog een klein wonder heten dat deze mailtjes deels doorkomen want in wezen klopt er niets van de structuur. Waarschijnlijk is het mailprogramma nog zo tolerant dat deze de foto's hier uit kan vissen, maar $bericht beschouwt als "rotzooi aan het einde van het bericht", deze heeft immers geen boundary noch een content type...
EDIT: ook is het zo dat alles buiten boundaries simpelweg wordt genegeerd.
Bonus: chunk_split laat regeleindes intact, deze zou je moeten rtrimmen, anders bevatten je base64-encoded blokken teveel regelovergangen (witregels). Bekijk de bron van je e-mail bericht maar eens, waarschijnlijk bevatten je base64-encoded blokken witregels.
Rectificatie: mogelijk alleen aan het eind van de ge-chunk_split-te tekst, maar een regelovergang teveel of te weinig in een MIME-mail kan vervelend zijn, kijk dit dus na!
Dit laatste (bron van e-mailbericht bekijken) heb je waarschijnlijk nog niet gedaan, anders had je deze fouten al gespot.
Gewijzigd op 02/10/2015 15:10:24 door Thomas van den Heuvel
@Rickert Twee zielen een gedachte. Ik heb uiteindelijk ook voor PHPMailer gekozen :) Ik ben er alleen nog niet uit hoe ik de attachements als image kan late zien in de email i.p.v. text
@Thomas Dacht misschien te makkelijk. Had dit klakkeloos over genomen uit een tutorial met wat aanpassingen, vandaar dus nu phpMailer zoals boven beschreven.
Om images echt in je email weer te geven en niet als bijlage zul je je email in HTML moeten opstellen.
Hiervoor valt PHPMailer (of Swift) zeker wel aan te bevelen inderdaad. Je kunt op twee manieren te werk gaan.
a) Je kunt de afbeeldingen online zetten en met een absolute url naar deze afbeelingen verwijzen:
Nadeel: veel emailprogramma's zullen de afbeeldingen blokkeren.
Voordeel: kleine omvang van je bericht.
b) Je zendt de afbeeldingen mee als attachments en verwijst in je HTML naar deze attachments:
Voordeel: geen blokkade
Nadeel: grote omvang van je bericht.
Gewijzigd op 02/10/2015 18:59:47 door Frank Nietbelangrijk
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$foto_path = APP_PATH.'/../public_html/images/uploads/' . $uniqid . '/';
$nieuw_path = mkdir($foto_path, 0777);
for ($i = 0; $i < count($_FILES['file']['name']); $i++)
{
$foto_naam = $_FILES['file']['name'][$i];
$nieuw_foto_path = $foto_path . $foto_naam;
if(move_uploaded_file($_FILES["file"]["tmp_name"][$i], $nieuw_foto_path))
{
$mail->addAttachment($nieuw_foto_path);
}
}
if($mail->Send()) {
$dir = $foto_path;
array_map('unlink', glob($dir."/*"));
rmdir($dir);
}
$nieuw_path = mkdir($foto_path, 0777);
for ($i = 0; $i < count($_FILES['file']['name']); $i++)
{
$foto_naam = $_FILES['file']['name'][$i];
$nieuw_foto_path = $foto_path . $foto_naam;
if(move_uploaded_file($_FILES["file"]["tmp_name"][$i], $nieuw_foto_path))
{
$mail->addAttachment($nieuw_foto_path);
}
}
if($mail->Send()) {
$dir = $foto_path;
array_map('unlink', glob($dir."/*"));
rmdir($dir);
}
Met andere woorden eerst creëerde ik een nieuwe folder op basis van een eerder aangemaakte uniqid() waar de foto's tijdelijk werden geplaatst en in de loop voegde ik die vervolgens aan het bericht toe. Wanneer de email dan succesvol verzonden was verwijderde ik die nieuwe folder en inhoud weer. Zoals gezegd dit werkte prima alleen is de situatie iets veranderd. Er is namelijk een betaal module tussen gekomen. Dus nu als de gebruiker het formulier verzend worden de n.a.w. gegevens en de foto namen in de database opgeslagen en de foto's geüpload naar de zoals boven beschreven folder waarna de gebruiker naar IDEAL wordt gestuurd. Bij een succesvolle betaling wordt de gebruiker terug gestuurd naar de website en wordt phpMailer geactiveerd en zou de eerder genoemde loop uitgevoerd moeten worden. Maar daar gaat het dus fout. De n.a.w.gegevens worden netjes verstuurd maar de toevoegingen worden niet mee gestuurd. Dit is wat ik hiervoor gebruik:
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
$foto_path = APP_PATH.'/../public_html/images/uploads/' . $uniqid . '/';
$gebruikers_fotos = $this->page->get_gebruikers_fotos($uniqid);
foreach ($gebruikers_fotos as $foto)
{
$foto_naam = $_FILES['file']['name'][$i];
$nieuw_foto_path = $foto_path . $foto_naam;
$mail->addAttachment($nieuw_foto_path);
}
$gebruikers_fotos = $this->page->get_gebruikers_fotos($uniqid);
foreach ($gebruikers_fotos as $foto)
{
$foto_naam = $_FILES['file']['name'][$i];
$nieuw_foto_path = $foto_path . $foto_naam;
$mail->addAttachment($nieuw_foto_path);
}
De $uniqid is gebruikt als identifier van en naar IDEAL en die werkt want daar haal ik tevens de gebruikers informatie mee uit de database die zoals gezegd wel in de email wordt verstuurd. Wat is er dus foout met het gedeelte waar de foto's toegevoegd zouden moeten worden?
Bij voorbaat dank
Daarnaast: ontwikkel je niet met error reporting aan? Dat zou direct een "undefined index" moeten opleveren.
Tevens: plemp jij alle foto's in de publieke webdirectory? Cool. Dus als iemand de uniqid raadt (of gewoon bruteforced) dan kan die bij iemands foto's? Nice.
Waarom niet gewoon: Foto's buiten webdirectory opslaan en gewoon nummeren (hernoemen naar een nummer) en alle relevante data omtrent een foto ook opslaan in de database zodat als er ergens iets misgaat onderweg dat iemand niet zijn/haar foto's opnieuw hoeft te uploaden, en je hebt tevens een reservekopie?
Hiermee kan je gemakkelijk bestanden beheren en uploaden e.d
Werkt echt super.
Dat maakt je script overzichtelijk en behoudt zijn functionaliteiten.
- PHPmailer
- Upload class Verot.net
http://www.verot.net/php_class_upload.htm