[RESOLU] Petit problème download vcard

llo75x
Invité n'ayant pas de compte PHPfrance

29 juin 2015, 12:13

Bonjour,
je suis débutant et c'est mon 1er post. Voilà tout est dit.
Je veux faire un bouton qui permette à l'utilisateur de télécharger une vcard.
Celle-ci est créé à la volée par le serveur.
<?php
	$rc=chr(13).chr(10);
	$prenom="toto";
	$nom="nomàtoto";
	$email="emailàtoto";
	$mobile="mobileàtoto";
	// Open the text file
	$f = fopen("toto.vcf", "w");
	fwrite($f, "BEGIN:VCARD".$rc."VERSION:3.0".$rc);
	fwrite($f, "N:Contact;iPhone;;;".$rc);
	fwrite($f, "FN:".$prenom.' '.$nom.$rc);
	fwrite($f, "EMAIL;type=INTERNET;type=WORK;type=pref:".$email.$rc);
	fwrite($f, "TEL;type=CELL;type=VOICE;type=pref:".$mobile.$rc);
	fwrite($f, "END:VCARD".$rc);
	// Close the text file
	fclose($f);
?>
c'est le 1er script PHP tout simple qui ecrit un fichier text avec extension .vcf sur le serveur
J'ai un 2e script, peché sur internet qui permet le téléchargement.
chacun fonctionne correctement séparément, mais à la suite ça marche pas. Je clarifie. Si j'appelle dans la barre d'adresse le script writevcard.php => il marche. puis si j'appelle dans la barre d'adresse dl.php . il marche.
mais si je mets les 2 à la suite dans le même script ou que je les appelle à la suite à partir d'un 3e script. le download se contente s'afficher les echo à l'écran voire rien.
Merci de votre aide

dl.php
<?php
    # Send correct headers      
    header("Content-type: text/x-vcalendar; charset=utf-8"); 
                    // Alternatively: application/octet-stream
                    // Depending on the desired browser behaviour
                    // Be sure to test thoroughly cross-browser

    header("Content-Disposition: attachment; filename=\"toto.vcf\";");
    
    # Generate file contents - advanced version
    # BEGIN:VCALENDAR
    # VERSION:2.0
    # BEGIN:VEVENT
    # DTSTART;TZID=Europe/London:20120617T090000
    # DTEND;TZID=Europe/London:20120617T100000
    # SUMMARY:iPhone Contact
    # DTSTAMP:20120617T080516Z
    # ATTACH;VALUE=BINARY;ENCODING=BASE64;FMTTYPE=text/directory;
    #  X-APPLE-FILENAME=toto.vcf:
    #  QkVHSU46VkNBUkQNClZFUlNJT046My4wDQpOOkNvbnRhY3Q7aVBob25lOzs7DQpGTjppUGhvbm
    #  UgQ29udGFjdA0KRU1BSUw7VFlQRT1JTlRFUk5FVDtUWVBFPVdPUks6aXBob25lQHRoZXNpbGlj
    #  b25nbG9iZS5jb20NClRFTDtUWVBFPUNFTEw7VFlQRT1WT0lDRTtUWVBFPXByZWY6KzQ0MTIzND
    #  U2Nzg5MA0KRU5EOlZDQVJE
    # END:VEVENT
    # END:VCALENDAR

    echo "BEGIN:VCALENDAR\n";
    echo "VERSION:2.0\n";
    echo "BEGIN:VEVENT\n";
    echo "SUMMARY:Click attached contact below to save to your contacts\n";
    $dtstart = date("Ymd")."T".date("Hi")."00";
    echo "DTSTART;TZID=Europe/London:".$dtstart."\n";
    $dtend = date("Ymd")."T".date("Hi")."01";
    echo "DTEND;TZID=Europe/London:".$dtend."\n";
    echo "DTSTAMP:".$dtstart."Z\n";
    echo "ATTACH;VALUE=BINARY;ENCODING=BASE64;FMTTYPE=text/directory;\n";
    echo " X-APPLE-FILENAME=toto.vcf:\n";
    $vcard = file_get_contents("toto.vcf");        # read the file into memory
    $b64vcard = base64_encode($vcard);                      # base64 encode it so that it can be used as an attachemnt to the "dummy" calendar appointment
    $b64mline = chunk_split($b64vcard,74,"\n");             # chunk the single long line of b64 text in accordance with RFC2045 (and the exact line length determined from the original .ics file exported from Apple calendar
    $b64final = preg_replace('/(.+)/', ' $1', $b64mline);   # need to indent all the lines by 1 space for the iphone (yes really?!!)
    echo $b64final;                                         # output the correctly formatted encoded text
    echo "END:VEVENT\n";
    echo "END:VCALENDAR\n";
 ?>

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

29 juin 2015, 12:26

Bonjour,

Si tu mets les deux scripts à la suite ou si tu les inclus dans un 3e, il faut t'assurer qu'aucune information n'est envoyée au navigateur avant l'appel aux headers() de ton second script. Il ne faut donc pas d'echo, de print, ..., ni d'espace ou de retour à la ligne en dehors des balises <?php / ?>
Dans un même fichier, il ne faut pas :
// Close the text file
  fclose($f);
?>
<?php
    # Send correct headers
Dans ce cas, un retour à la ligne (entre les balises php) est envoyé au navigateur avant qu'il ne reçoive le header :)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

29 juin 2015, 12:29

Bonjour et bienvenue sur PHPfrance ! :-)

Comment est-ce que ton utilisateur accède au téléchargement du fichier VCF ?
Si c'est pas un lien de téléchargement dans une page HTML, alors il suffit que tu fasses un lien classique vers ton fichier dl.php :
<a href="dl.php">Télécharger la vcard</a>
Ensuite pour mixer les deux codes pour tout générer à la volée, je pense qu'il est préférable d'éviter d'écrire le fichier vcf sur le disque mais plutôt de mettre son contenu dans une variable :
$rc=chr(13).chr(10);
  $prenom="toto";
  $nom="nomàtoto";
  $email="emailàtoto";
  $mobile="mobileàtoto";
  // Open the text file
$vcard="BEGIN:VCARD".$rc."VERSION:3.0".$rc;
$vcard.="N:Contact;iPhone;;;".$rc;
$vcard.="FN:".$prenom.' '.$nom.$rc;
$vcard.="EMAIL;type=INTERNET;type=WORK;type=pref:".$email.$rc;
$vcard.="TEL;type=CELL;type=VOICE;type=pref:".$mobile.$rc;
$vcard.="END:VCARD".$rc;
Et ensuite, tu as juste à insérer ce code à la place de la récupération du fichier vcf, c'est à dire à la place de
$vcard = file_get_contents("toto.vcf");
Quand tout le reste a échoué, lisez le mode d'emploi...

llo75x
Invité n'ayant pas de compte PHPfrance

29 juin 2015, 18:40

@ryle : effectivement c'était le problème. Mais en fait la solution d'@rthur était plus simple. "pourquoi passer par un fichier puisque je remet tout dans une variable. Parfois on se complique tellement la vie alors qu'on peut simplifier....
Merci à tous les 2 pour votre précieuse aide.