[RESOLU] php preview d'une url

Eléphant du PHP | 385 Messages

04 avr. 2017, 00:25

Bonjour à tous,

Je galère sur un problème pourriez vous m'aider s'il vous plaît?
Je suis sur un petit projet symfony, à l'intérieur je veux que si je poste une url cela m'affiche une preview c'est à dire image plus text.
Seul problème, j'ai eu beau cherché je suis tombé sur des codes qui sont assez compliqué à intégrer:

https://github.com/kasp3r/link-preview
https://github.com/LeonardoCardoso/Face ... nk-Preview

j'ai pensé aussi à seulement utilisait une iframe.
Ce que je voudrais c'est généré un peux quelque chose comme sur ce lien
https://richpreview.com/

Vous me conseiller de coder mon propre script ou je prend un script existant que j'intègre en le modifiant? A partir d'un lien comment fait on pour savoir quel image correspond à l'article, ou encore le texte?

Merci.

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

04 avr. 2017, 09:27

Bonjour,

L'iframe est a oublier car très lourd à charger et le rendu va être pas propre du tout.

Ce qu'il faut pour quelque chose de basique ce n'est pas très compliqué c'est récupérer le contenu des balises <title> et <meta (description + celles de l'open graph si présentes)
Tu as en PHP la fonction get_meta_tags() qui peut t'aider : http://php.net/manual/fr/function.get-meta-tags.php

Après l'avantage d'une librairie déjà existante c'est qu'elle va probablement gérer directement les cas particulier par exemple d'un site qui n'a pas de titre ou de description ou d'image d'aperçu...
Quand tout le reste a échoué, lisez le mode d'emploi...

Eléphant du PHP | 385 Messages

06 avr. 2017, 09:11

Merci @rthur,

J'ai crée un service symfony

Code : Tout sélectionner

<?php namespace socialNetworkBundle\services; class PreviewLinkInformation { private $_contentUrl; private $_urlValid = false; public function ContentUrl() { return $this->_contentUrl; } public function setContentUrl($url) { $str = file_get_contents($url); if(strlen($str)>0) { $this->_urlValid = true; $this->_contentUrl = $str; } else { $this->_urlValid = false; } } function getTitle(){ if($this->_urlValid) { $str = preg_replace('/\s+/', ' ', $this->ContentUrl()); preg_match("/\<title\>(.*)\<\/title\>/i",$this->ContentUrl() ,$title); // ignore case return $title[1]; } } }
puis pour tester avec mon controller, j'utilise un lien

Code : Tout sélectionner

public function indexAction() { $utils = $this->container->get('PreviewLinkInformation'); $utils->setContentUrl('http://php.net/manual/fr/domelement.getelementsbytagname.php'); echo $utils->getTitle();exit; $em = $this->getDoctrine()->getManager(); $items = $em->getRepository('socialNetworkBundle:Item')->findAll(); return $this->render('socialNetworkBundle:Default:index.html.twig', array( 'items' => $items, )); } }
Seul problème comme vous le dite il y a certains site qui on très peux de méta [url]view-source:http://php.net/manual/fr/domelement.get ... agname.php[/url] , du coup comment je peux faire pour récupérer le contenu? également sur un site comme http://www.20minutes.fr/planete/2044579 ... ire-france pour l'image de la preview il y a si je veux récupérer l'image pour la preview de l'article comment je sais que c'est cette image et pas une autre sachant que les balises ne donne pas trop d'indication?

Merci pour votre aide.

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

06 avr. 2017, 18:55

La plupart des gros sites indiquent des données pour l'opengraph de Facebook, justement pour indiquer quelle image il faut utiliser pour illustrer la page.
C'est indiquer dans la balise meta name="og:image"

Dans le cas de ton exemple, c'est cette image qui est indiquée : https://img.20mn.fr/iR5jOD-kQoeIpyifz-C ... m-lorraine
Quand tout le reste a échoué, lisez le mode d'emploi...

Eléphant du PHP | 385 Messages

11 avr. 2017, 22:17

Merci,

J'ai essayé de passer par get_meta_tags mais la fonction ne récupère pas tous les paramètre finalement j'utilise cette focntion

Code : Tout sélectionner

private function MetaTagsRead() { if($this->_urlValid) { $site_html= file_get_contents($this->Url()); $pattern = ' ~<\s*meta\s # using lookahead to capture type to $1 (?=[^>]*? \b(?:name|property|http-equiv)\s*=\s* (?|"\s*([^"]*?)\s*"|\'\s*([^\']*?)\s*\'| ([^"\'>]*?)(?=\s*/?\s*>|\s\w+\s*=)) ) # capture content to $2 [^>]*?\bcontent\s*=\s* (?|"\s*([^"]*?)\s*"|\'\s*([^\']*?)\s*\'| ([^"\'>]*?)(?=\s*/?\s*>|\s\w+\s*=)) [^>]*> ~ix'; if(preg_match_all($pattern, $site_html, $out)) $tag = array_combine($out[1], $out[2]); $this->setMetaTags($tag); } }
puis dans mon controlleur

Code : Tout sélectionner

public function indexAction() { $MetaTags = $this->container->get('PreviewLinkInformation'); $em = $this->getDoctrine()->getManager(); $items = $em->getRepository('socialNetworkBundle:Item')->findAll(); foreach ($items as $item) { $MetaTags->setUrl($item->getUrl()); $meta = $MetaTags->MetaTags(); if(!empty($meta['og:image'])) $item->setUrlImage($meta['og:image']); if(!empty($meta['twitter:title'])) $item->setTitle($meta['twitter:title']); } return $this->render('socialNetworkBundle:Default:index.html.twig', array( 'items' => $items, )); }