[php] Gegenereerde bijlage meezenden - PHPMailer

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • radem205
  • Registratie: Juni 2002
  • Laatst online: 02-02-2022
Hey,

Ik wil een gegenereerde bijlage (een pdf bestand dat gegenereerd wordt door het aanroepen van een php bestand) meezenden als bijlage bij een e-mail. Nu gebruik ik hiervoor PHPMailer, maar wanneer ik het volgende doe krijg ik de foutmelding "Could not access file: profielpdf.php?id=497":

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
<?
require 'phpmailer/class.phpmailer.php';

try {
    $mail = new PHPMailer(true); //New instance, with exceptions enabled

    $body             = 'Testemail';

    $mail->IsSMTP();                           // tell the class to use SMTP
    $mail->SMTPAuth   = true;                  // enable SMTP authentication
    $mail->Port       = 25;                    // set the SMTP server port
    $mail->Host       = "mail.*******.nl"; // SMTP server
    $mail->Username   = "*******";     // SMTP server username
    $mail->Password   = "*******";            // SMTP server password

    $mail->From       = "*******";
    $mail->FromName   = "*******";

    $to = "*******";

    $mail->AddAddress($to);

    $mail->Subject  = "Tesemail";

    $mail->AltBody    = "To view the message, please use an HTML compatible email viewer!"; 
    $mail->WordWrap   = 80; // set word wrap

    $mail->MsgHTML($body);

    $mail->IsHTML(true); // send as HTML
    
    $mail->AddAttachment('profielpdf.php?id=497','Profiel.pdf','base64','application/octet-stream');
        
    $mail->Send();
    
    echo 'Message has been sent.';
    
    
} catch (phpmailerException $e) {
    echo $e->errorMessage();
}
?>


Ik gebruik TCPDF om in het bestand profiel.php een pdf te creëren. Is het überhaupt mogelijk om met phpmailer een dynamisch gegenereerd pdf bestand te verzenden per mail?

In het bestand TCPDF kan ik de output zetten op:

* I: send the file inline to the browser. The plug-in is used if available. The name given by name is used when one selects the "Save as" option on the link generating the PDF.
* D: send to the browser and force a file download with the name given by name.
* F: save to a local file with the name given by name.
* S: return the document as a string. name is ignored.

Echter geen één van allen werkt in combinatie met PHPMailer.

Heeft iemand een idee waar dit aan kan liggen? Ik heb ook geprobeerd om de addStringAttachment te gebruiken (in profielpdf.php de output ook op string (S) gezet), maar dat werkt helaas niet :(.

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Wordt profielpdf.php uberhaupt aangeroepen? Heb je dat getest? Zo niet, misschien helpt 't om er een volledige (en anders absolute/relatieve) url van te maken. Anders zou je kunnen proberen de PDF op te halen met CURL of iets dergelijks (fopen() in PHP kan geloof ik ook, maar ik ben geen PHP-kenner :P )

[ Voor 33% gewijzigd door RobIII op 02-02-2010 12:43 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • radem205
  • Registratie: Juni 2002
  • Laatst online: 02-02-2022
Ja, sorry dat ik dat niet vermeld heb. Ik heb absolute paden geprobeerd (m.b.v. $_SERVER['DOCUMENT_ROOT'] en de volledige url), maar dat helpt niet, helaas :( ).

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
radem205 schreef op dinsdag 02 februari 2010 @ 12:43:
Ja, sorry dat ik dat niet vermeld heb. Ik heb absolute paden geprobeerd (m.b.v. $_SERVER['DOCUMENT_ROOT'] en de volledige url), maar dat helpt niet, helaas :( ).
Dus heel die PHP wordt nooit aangeroepen? Lijkt me dat daar je probleem zit dan ;)
As said: probeer 'm eens op een andere manier te openen (curl, fopen(), weet_ik_wat).

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

Is het misschien geen idee om een (apart) PHP-script te maken die het volgende doet:
Als eerste PDF maken en wegschrijven op lokale bestandssysteem. (maak dus een variabele waar het document opgeslagen is)

Daarna met PHPMailer de mail maken en vervolgens de bij stap 1 gegenereerde bestandslocatie toevoegen als bijlage in de mail.

Derde stap is dan vervolgens om de PDF van het bestandssysteem te verwijderen, om te voorkomen dat het filesystem vol loopt.

Acties:
  • 0 Henk 'm!

  • webinn
  • Registratie: Oktober 2002
  • Laatst online: 06-06 12:44
GJtje schreef op dinsdag 02 februari 2010 @ 12:50:
Is het misschien geen idee om een (apart) PHP-script te maken die het volgende doet:
Als eerste PDF maken en wegschrijven op lokale bestandssysteem. (maak dus een variabele waar het document opgeslagen is)

Daarna met PHPMailer de mail maken en vervolgens de bij stap 1 gegenereerde bestandslocatie toevoegen als bijlage in de mail.

Derde stap is dan vervolgens om de PDF van het bestandssysteem te verwijderen, om te voorkomen dat het filesystem vol loopt.
zo doe ik het ook en dat werkt alleszins perfect

Acties:
  • 0 Henk 'm!

  • Nick_S
  • Registratie: Juni 2003
  • Laatst online: 18-09 22:40

Nick_S

++?????++ Out of Cheese Error

Zo te zien verwacht PHPMailer.addAttachment een bestandslocatie op het filesysteem, dus geen URL. Je kan met PHP: tmpFile een tijdelijk bestand aanmaken, waarin je dus met behulp van de 'S' optie de gegenereerde PDF kan wegschrijven en daarna deze tmp file meegeven aan PHPMailer.

Voordeel van php tmp is dat je niet zelf voor bestandsopruiming hoeft te zorgen. Dus als je script een exceptie genereerd hoef je niet naar de file om te kijken. Deze wordt vanzelf opgeruimd.

Totaal geen PHP ervaring, maar dit is wat ik kon vinden met even Google gebruiken

'Nae King! Nae quin! Nae Laird! Nae master! We willna' be fooled agin!'


Acties:
  • 0 Henk 'm!

  • KabouterSuper
  • Registratie: September 2005
  • Niet online
ik zou gaan voor de inline attachment. Als je je php-code van je pdf-pagina zo kunt ombouwen dat deze de inhoud teruggeeft in een variabele, dan kan je deze in phpmailer gebruiken.

When life gives you lemons, start a battery factory


Acties:
  • 0 Henk 'm!

  • Nick_S
  • Registratie: Juni 2003
  • Laatst online: 18-09 22:40

Nick_S

++?????++ Out of Cheese Error

KabouterSuper schreef op dinsdag 02 februari 2010 @ 13:22:
ik zou gaan voor de inline attachment. Als je je php-code van je pdf-pagina zo kunt ombouwen dat deze de inhoud teruggeeft in een variabele, dan kan je deze in phpmailer gebruiken.
Die functie had ik inderdaad over het hoofd gezien, maar dat is ook niet zo raar gezien de naamgeving. :S
AddEmbeddedImage($path, $cid, $name = "", $encoding = "base64", $type = "application/octet-stream")

Adds an embedded attachment. This can include images, sounds, and just about any other document. Make sure to set the $type to an image type. For JPEG images use "image/jpeg" and for GIF images use "image/gif". If you use the MsgHTML() method, there is no need to use AddEmbeddedImage() method.

'Nae King! Nae quin! Nae Laird! Nae master! We willna' be fooled agin!'


Acties:
  • 0 Henk 'm!

  • radem205
  • Registratie: Juni 2002
  • Laatst online: 02-02-2022
KabouterSuper schreef op dinsdag 02 februari 2010 @ 13:22:
ik zou gaan voor de inline attachment. Als je je php-code van je pdf-pagina zo kunt ombouwen dat deze de inhoud teruggeeft in een variabele, dan kan je deze in phpmailer gebruiken.
Ik denk dat dit de beste oplossing is, echter wanneer ik nu het bestand "profielpdf.php?id=321" in de browser open krijg ik een string te zien. Hoe kan ik deze in een ander php bestand in een variabele stoppen en toevoegen aan AddEmbeddedImage? File_get_contents werkt niet, evenals fopen.

[ Voor 3% gewijzigd door radem205 op 02-02-2010 13:38 ]


Acties:
  • 0 Henk 'm!

  • Nick_S
  • Registratie: Juni 2003
  • Laatst online: 18-09 22:40

Nick_S

++?????++ Out of Cheese Error

radem205 schreef op dinsdag 02 februari 2010 @ 13:35:
[...]


Ik denk dat dit de beste oplossing is, echter wanneer ik nu het bestand "profielpdf.php?id=321" in de browser open krijg ik een string te zien. Hoe kan ik deze in een ander php bestand in een variabele stoppen en toevoegen aan AddEmbeddedImage?
Dat is al terloops genoemd in dit topic: fopen.

Edit: Ik zie dat file_get_contents misschien makkelijker werkt.

[ Voor 12% gewijzigd door Nick_S op 02-02-2010 13:40 ]

'Nae King! Nae quin! Nae Laird! Nae master! We willna' be fooled agin!'


Acties:
  • 0 Henk 'm!

  • radem205
  • Registratie: Juni 2002
  • Laatst online: 02-02-2022
Nick_S schreef op dinsdag 02 februari 2010 @ 13:37:
[...]

Dat is al terloops genoemd in dit topic: fopen.
Sorry, was te laat met editten van mijn vorige post, maar als ik fopen gebruik krijg ik (ook met relatieve paden):

fopen(c:\domains\h*********\wwwroot\beheer\profielpdf.php?id=504) [function.fopen]: failed to open stream: No such file or directory

Terwijl het adres goed is...

Edit: Het lijkt alsof er geen variabelen in het adres mogen voorkomen (dus ?id=321 mag niet). Als ik dat weg haal doet de file_get_contents het wel. Iemand enig idee?

[ Voor 14% gewijzigd door radem205 op 02-02-2010 13:43 ]


Acties:
  • 0 Henk 'm!

  • Nick_S
  • Registratie: Juni 2003
  • Laatst online: 18-09 22:40

Nick_S

++?????++ Out of Cheese Error

Je "adres" is niet goed. Je probeert nu een lokaal bestand te openen met parameter. Dit gaat nooit werken. Je zal je php bestand altijd via php moeten laten lopen, dus openen op url basis, zodat het request uitkomt bij je Apache/IIS/andere php service.

'Nae King! Nae quin! Nae Laird! Nae master! We willna' be fooled agin!'


Acties:
  • 0 Henk 'm!

  • radem205
  • Registratie: Juni 2002
  • Laatst online: 02-02-2022
Nick_S schreef op dinsdag 02 februari 2010 @ 13:43:
Je "adres" is niet goed. Je probeert nu een lokaal bestand te openen met parameter. Dit gaat nooit werken. Je zal je php bestand altijd via php moeten laten lopen, dus openen op url basis, zodat het request uitkomt bij je Apache/IIS/andere php service.
Maar ook wanneer ik file_get_contents('profielpdf.php?id=423') geeft ie aan dat het bestand niet kan worden gevonden. Wanneer ik ?id=423 weg haal dan werkt het wel :s

Acties:
  • 0 Henk 'm!

  • KabouterSuper
  • Registratie: September 2005
  • Niet online
Ik doelde op de functie AddStringAttachment, niet op AddEmbeddedImage.....maar ik had het niet echt handig omschreven. Deze functie heeft als input een string in plaats van een lokatie. De string genereer je door de php-file te includen die de pdf-file genereert. Je hoeft dan alleen nog maar te zorgen dat de php-file de pdf-file niet echo't, maar het teruggeeft in een variabele.

When life gives you lemons, start a battery factory


Acties:
  • 0 Henk 'm!

  • radem205
  • Registratie: Juni 2002
  • Laatst online: 02-02-2022
KabouterSuper schreef op dinsdag 02 februari 2010 @ 13:46:
Ik doelde op de functie AddStringAttachment, niet op AddEmbeddedImage.....maar ik had het niet echt handig omschreven. Deze functie heeft als input een string in plaats van een lokatie. De string genereer je door de php-file te includen die de pdf-file genereert. Je hoeft dan alleen nog maar te zorgen dat de php-file de pdf-file niet echo't, maar het teruggeeft in een variabele.
Het zorgen dat de php file de pdf-file niet echo't, maar het in een variabele teruggeeft is juist het probleem. Het bestand profielpdf.php?id=321 echo't nu wel de inhoud, want wanneer ik de output op string zet (in TCPDF) en ik echo de string niet dan blijft het bestand leeg toch?
En om één of andere reden kan ik geen variabele in het adres meesturen wanneer ik file_get_contents of fopen gebruik.

Acties:
  • 0 Henk 'm!

  • Nick_S
  • Registratie: Juni 2003
  • Laatst online: 18-09 22:40

Nick_S

++?????++ Out of Cheese Error

radem205 schreef op dinsdag 02 februari 2010 @ 13:45:
[...]


Maar ook wanneer ik file_get_contents('profielpdf.php?id=423') geeft ie aan dat het bestand niet kan worden gevonden. Wanneer ik ?id=423 weg haal dan werkt het wel :s
Ik denk dat de verschillende functies binnen php alleen op URL werken, als je ze ook een URL geeft. Dus iets in de vorm van [protocol]://[host]:[port]/[location]. Probeer dus nog even te kijken wat er gebeurt als je een valide URL meegeeft.

'Nae King! Nae quin! Nae Laird! Nae master! We willna' be fooled agin!'


Acties:
  • 0 Henk 'm!

  • Nick_S
  • Registratie: Juni 2003
  • Laatst online: 18-09 22:40

Nick_S

++?????++ Out of Cheese Error

radem205 schreef op dinsdag 02 februari 2010 @ 13:49:
[...]


Het zorgen dat de php file de pdf-file niet echo't, maar het in een variabele teruggeeft is juist het probleem. Het bestand profielpdf.php?id=321 echo't nu wel de inhoud, want wanneer ik de output op string zet (in TCPDF) en ik echo de string niet dan blijft het bestand leeg toch?
En om één of andere reden kan ik geen variabele in het adres meesturen wanneer ik file_get_contents of fopen gebruik.
Je zou bijvoorbeeld kunnen proberen om van je profielpdf pagina, geen pagina te maken, maar een klasse, welke de inhoud als string teruggeeft. Dan kun je deze klasse aanroepen en zodoende de inhoud binnen halen, zonder naar een extern proces te gaan zoals je met fopen of get_contents doet.

'Nae King! Nae quin! Nae Laird! Nae master! We willna' be fooled agin!'


Acties:
  • 0 Henk 'm!

  • KabouterSuper
  • Registratie: September 2005
  • Niet online
Je schrijft zelf:
code:
1
2
3
4
5
6
In het bestand TCPDF kan ik de output zetten op:

* I: send the file inline to the browser. The plug-in is used if available. The name given by name is used when one selects the "Save as" option on the link generating the PDF.
* D: send to the browser and force a file download with the name given by name.
* F: save to a local file with the name given by name.
* S: return the document as a string. name is ignored.


De optie S doet toch wat je wil.....of vergis ik me?

Als het je echt niet lukt, dan moet je terugvallen op curl. Deze moet je php-versie wel ondersteunen. Syntax is pakweg ($url is je http-locatie):
code:
1
2
3
4
5
6
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
        $store = curl_exec ($ch);
        $total_data = curl_exec ($ch); # This returns HTML
        curl_close ($ch);

$total_data is de string die je gebruikt in de functie AddStringAttachment.

[ Voor 0% gewijzigd door KabouterSuper op 02-02-2010 13:55 . Reden: http-locatie bold gemaakt, want dit is vrij cruciaal ]

When life gives you lemons, start a battery factory


Acties:
  • 0 Henk 'm!

  • radem205
  • Registratie: Juni 2002
  • Laatst online: 02-02-2022
Ok top, het werkt nu. Echter heb ik profielpdf.php een beveiliging ingebouwd om te zorgen dat je ingelogd moet zijn om de pdf te kunnen bekijken / downloaden.

PHP:
1
2
$path = file_get_contents('http://www.domein.nl/profielpdf.php?id=321');
echo $path;


Nu weet ik zeker dat ik ben ingelogd, maar wanneer ik bovenstaande code uitvoer dan krijg ik altijd de pagina "inloggen.php" te zien.

Deze code gebruik ik om te controleren of iemand is ingelogd:

PHP:
1
2
3
4
if(!checkStatus()) {
    header("Location: inloggen.php?ref=".createReferer());
    exit;
}


Wanneer ik bovenstaande code verwijder dan werkt het allemaal nabehoren. Kan het zijn dan $_SESSION's niet worden onthouden in de file_get_contents functie?

Acties:
  • 0 Henk 'm!

  • KabouterSuper
  • Registratie: September 2005
  • Niet online
Je kunt wel sessie parameters meegeven (stream_context_create), maar het kost wel wat moeite om dit werkend te krijgen.

When life gives you lemons, start a battery factory


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
radem205 schreef op dinsdag 02 februari 2010 @ 14:05:
Wanneer ik bovenstaande code verwijder dan werkt het allemaal nabehoren. Kan het zijn dan $_SESSION's niet worden onthouden in de file_get_contents functie?
Ik denk dat je eens een stap achteruit moet doen en goed moet nadenken wat er nou eigenlijk gebeurt ;)

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • radem205
  • Registratie: Juni 2002
  • Laatst online: 02-02-2022
Ok, ik heb het opgelost (niet 100% veilig) door middel van een md5hash te controleren. Denk dat dit wel voldoende is. Hartelijk dank voor jullie aangedragen mogelijkheden cq oplossing!!

Acties:
  • 0 Henk 'm!

  • MueR
  • Registratie: Januari 2004
  • Nu online

MueR

Admin Tweakers Discord

is niet lief

Wacht even, je hebt hier nog wat plakband en touw laten liggen. Die ga je nog nodig hebben om dit geheel bij elkaar te houden!

Met andere woorden, deze oplossing is zo brak als iets. Je hebt je probleem "opgelost" door via een http request een pdf op te halen, terwijl je die beter gewoon op het moment van emailen kan genereren.

Anyone who gets in between me and my morning coffee should be insecure.


Acties:
  • 0 Henk 'm!

  • radem205
  • Registratie: Juni 2002
  • Laatst online: 02-02-2022
MueR schreef op dinsdag 02 februari 2010 @ 14:32:
Wacht even, je hebt hier nog wat plakband en touw laten liggen. Die ga je nog nodig hebben om dit geheel bij elkaar te houden!

Met andere woorden, deze oplossing is zo brak als iets. Je hebt je probleem "opgelost" door via een http request een pdf op te halen, terwijl je die beter gewoon op het moment van emailen kan genereren.
Haha, het plakband is op dus ik moet wat anders verzinnen, wil je mij helpen :)? Nee, maar hoe had jij het in gedachte dan? Want wanneer ik de pdf genereer op het moment van emailen dan heb ik 2 aparte bestanden (1 om te emailen en 1 om de pdf te downloaden) om de pdf te genereren, echter doordat er nog zo nu en dan wijzigingen moeten worden aangebracht in de pdf opzet is het handiger om dit bij één bestand te houden die de pdf genereert (of ik moet het genereren van een pdf in een functie zetten). Of heb je een veel beter idee?

[ Voor 3% gewijzigd door radem205 op 02-02-2010 14:37 ]


Acties:
  • 0 Henk 'm!

  • Nick_S
  • Registratie: Juni 2003
  • Laatst online: 18-09 22:40

Nick_S

++?????++ Out of Cheese Error

radem205 schreef op dinsdag 02 februari 2010 @ 14:36:
[...]
of ik moet het genereren van een pdf in een functie zetten.
Dit dus, of wat ik al eerder zei:
Je zou bijvoorbeeld kunnen proberen om van je profielpdf pagina, geen pagina te maken, maar een klasse, welke de inhoud als string teruggeeft. Dan kun je deze klasse aanroepen en zodoende de inhoud binnen halen, zonder naar een extern proces te gaan zoals je met fopen of get_contents doet.
Die klasse zou je dan zowel vanuit je mailer script als vanuit de losse pagina kunnen aanroepen, zodat je allebei de functionaliteiten hebt, maar wel de code op 1 plaats.

'Nae King! Nae quin! Nae Laird! Nae master! We willna' be fooled agin!'


Acties:
  • 0 Henk 'm!

  • Raynman
  • Registratie: Augustus 2004
  • Laatst online: 00:16
Bovenstaande zou inderdaad een logische (of: de enige juiste) stap zijn. Als je daar echt geen zin in hebt (zou niet weten waarom), kun je beter met output buffering spelen i.p.v. HTTP gebruiken en met md5hashes goochelen:
PHP:
1
2
3
4
5
6
7
<?php
$_GET['id'] = 321;
ob_start();
include('profielpdf.php');
$pdf = ob_get_clean();
//Disclaimer: mijn PHP is behoorlijk roestig en dit is geenszins getest.
?>

[ Voor 17% gewijzigd door Raynman op 02-02-2010 17:34 . Reden: iets duidelijker gemaakt dat plakband niet zo robuust is ]


Acties:
  • 0 Henk 'm!

  • radem205
  • Registratie: Juni 2002
  • Laatst online: 02-02-2022
Ik heb de adviezen opgevolgd en het creëren van een pdf in een functie gezet, waarbij ik zonodig het bestand met daarin de functie, include en de functie aanroep.

Bedankt voor het meedenken!!!

Acties:
  • 0 Henk 'm!

  • MueR
  • Registratie: Januari 2004
  • Nu online

MueR

Admin Tweakers Discord

is niet lief

Raynman schreef op dinsdag 02 februari 2010 @ 15:53:
Bovenstaande zou inderdaad een logische stap zijn. Als je daar echt geen zin in hebt, kun je beter met output buffering spelen i.p.v. HTTP gebruiken en met md5hashes goochelen:
Leuk, nog meer plakband. Ijsstokjes erbij om het geheel stevig te houden?

Zorg dat je dit soort PDFs altijd netjes via een class of functie genereerd, dan kan je het tenminste op meerdere plekken inzetten. Als je het goed opzet kan je zelfs verschillende soorten overzichten op een nette manier verwerken.

Anyone who gets in between me and my morning coffee should be insecure.

Pagina: 1