IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Faire du Multithreading et du traitement Asynchrone en PHP pour traiter plusieurs données à la fois


Sujet :

Langage PHP

  1. #1
    Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Octobre 2013
    Messages
    452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2013
    Messages : 452
    Points : 66
    Points
    66
    Par défaut Faire du Multithreading et du traitement Asynchrone en PHP pour traiter plusieurs données à la fois
    Bonjour.
    Comment faire du Multithreading en PHP dans mon cas sachant que j'ai déjà commencé en m'appuyant sur cURL et sa méthode "curl_multi_init" dans ma fonction "curlMulti" que j'ai après appelé dans la fonction "followLinks" (Ligne 79) qui se charge de suivre les liens de chaque URL et qui contient également la fonction "getDetails" qui est celle qui traite l'extraction des détails comme le titre, la description de chaque URL via "PHP-DomDocument".

    L'objectif principal pour moi est de traiter le plus rapidement possible et en parallèle tous les URLs à la fois (au même moment) dans un temps records. Et pour ça, comme je l'ai dit, j'ai décidé d'utiliser "curl_multi_init" mais aussi et surtout la librairie "https://github.com/reactphp/http" (Ligne 90 à 93) qui traite les requêtes HTTP de façon "Asynchrone" ici représentées par la fonction "getDetails" qui se charge de récupérer le titre des liens soumis à la fonction "followLinks".
    Comment donc corriger mon Code de sorte à faire du "Multithreading" et le traitement Asynchrone de sorte à récupérer ou extraire au même moment les données de tous les urls ???

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    <?php
    // Fonction MULTITHREADING - TRAITEMENT EN PARALLELE DE PLUSIEURS CRAWL A LA FOIS:
    function curlMulti($urls) {
     
    	$mh = curl_multi_init();	// Initialisation de la multi session cURL
     
    	// For each of the URLs in array
    	foreach ($urls as $id => $d) {
     
    		$ch[$id] = curl_init();	// Initialisation de la session cURL
     
    		$url = (is_array($d) && !empty($d['url'])) ? $d['url'] : $d;
     
    		curl_setopt($ch[$id], CURLOPT_URL, $url);
    		curl_setopt($ch[$id], CURLOPT_RETURNTRANSFER, TRUE);
    		curl_setopt($ch[$id], CURLOPT_SSL_VERIFYHOST, false);
    		curl_setopt($ch[$id], CURLOPT_SSL_VERIFYPEER, false);
    		curl_setopt($ch[$id], CURLOPT_FOLLOWLOCATION, true);
     
    		curl_multi_add_handle($mh, $ch[$id]);	// Ajout de sessions cURL à cURL multi session
     
    	}
     
    	$running = NULL;	// Définit $running sur NULL
     
    	do {
    		curl_multi_exec($mh, $running);	// Exécution de plusieurs sessions cURL en parallèle
    	} while ($running > 0);	// Tant que $running est supérieur à zéro
     
    	// For each cURL session
    	foreach($ch as $id => $content) {
    		$results[$id] = curl_multi_getcontent($content);	// Ajoute des résultats au tableau $results
    		curl_multi_remove_handle($mh, $content);	// Supprimer cURL multi session
    	}
     
    	curl_multi_close($mh);	// Fermeture de la multi session cURL
     
    	return $results;	// Renvoie le tableau des résultats
    }
     
    function followLinks($url) {
     
    	global $alreadyCrawled;
    	global $crawling;
     
    	$parser = new DomDocumentParser($url);
     
    	$linkList = $parser->getLinks();
     
    	foreach($linkList as $link) {
    		$href = $link->getAttribute("href");
     
    		if(strpos($href, "#") !== false) {
    			continue;
    		}
    		else if(substr($href, 0, 11) == "javascript:") {
    			continue;
    		}
     
     
    		$href = createLink($href, $url);
     
     
    		if(!in_array($href, $alreadyCrawled)) {
    			$alreadyCrawled[] = $href;
    			$crawling[] = $href;
    		}
     
    	}
     
    	// Instanciation de la Librairie React-HTTP basée sur ReactPHP (https://github.com/reactphp/http) importée tout en haut du Crawler (ce même fichier) pour rendre Asynchrone le Crawl:
    	$reactLoop = React\EventLoop\Factory::create();
    	$reactClient = new Browser($reactLoop);
     
    	$crawling = array_values(array_unique($crawling));	// Suppression des doublons du tableau et réindexation
     
    	// Remove an item from the array after we have crawled it. This prevents infinitely crawling the same page.
    	// Appel de la fonction "curlMulti" et transmission d'un tableau d'URL pour faire plusieurs requêtes curl en même temps:
    	$crawling = curlMulti($crawling);   
     
    	$freshCrawled = [];
     
    	// Follow each link in the crawling array.
    	foreach($crawling as $site) {
    		// Output the page title, descriptions, keywords, URL, Icon, Image, Video, Feeds, etc... This output is
    		// piped off to an external file using the command line.
    		// getDetails($site);
    		// On traite ici le Crawl de façon Asynchrone via la Librairie "React-HTTP" basée sur "ReactPHP":
    		$reactClient->get($site)
    					->then(function (\Psr\Http\Message\ResponseInterface $response) {
    						$freshCrawled[] = getDetails((string) $response->getBody());
    					}
    		);
     
    		// Remove an item from the array after we have crawled it. This prevents infinitely crawling the same page.
    		if (in_array($site, $freshCrawled)) {
    			$crawling = array_diff($crawling, array($site));
    		}
    	}
     
    	// Continue to follow each link in the crawling array.
    	foreach($crawling as $siteCrawledAgain) {
    		followLinks($siteCrawledAgain);
    	}
     
    }
     
    $startUrls = ['http://alibaba.com', 'http://lemonde.fr', 'http://amazon.com', 'http://baidu.com', 'http://yahoo.com'];
     
    // Begin the crawling process by crawling the starting link first (POUR UN NON MULTI-THREADING).
    // followLinks($startUrl);
     
    foreach($startUrls as $site) {
    	$siteTrim = trim($site);
    	$url = url_parser($siteTrim);
     
    	followLinks($url);											// On lance le Crawl effectif
    }
    ?>
    NB: Comment surtout, supprimer après chaque URL traité, l'URL en question qui vient d'être traité pour ne pas traiter plusieurs fois le même URL sachant que j'ai essayé de le faire de la ligne 96 à la ligne 98 sans être convaincu ???

    Merci de m'aider à parfaire mon code.

  2. #2
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 690
    Points : 20 211
    Points
    20 211
    Par défaut
    Il faut bien comprendre que asynchrone ne veux pas dire multithread; Ca veux juste dire qu'au moment on fait un appel, il n'est pas bloquant.

    PHP n'est pas adapté au traitement multithread.
    Il est possible de faire des choses avec pthread par exemple (uniquement CLI) ou plus récemment parallel mais c'est ,selon moi, pas l'outil adapté a ce genre de tache.

    Autant déléguer à langage capable de gérer ca de manière efficace (c++,java,go, etc ...)
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Octobre 2013
    Messages
    452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2013
    Messages : 452
    Points : 66
    Points
    66
    Par défaut
    Merci pour la réponse.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Spring MVC] Comment faire un traitement asynchrone
    Par Invité dans le forum Développement Web en Java
    Réponses: 3
    Dernier message: 07/07/2015, 12h27
  2. Réponses: 4
    Dernier message: 04/12/2008, 21h46
  3. [Stratégie] Traitement asynchrone suite à la validation d'un formulaire web
    Par El Saigneur dans le forum Développement Web en Java
    Réponses: 2
    Dernier message: 01/10/2008, 22h53
  4. Réponses: 5
    Dernier message: 12/06/2008, 23h49
  5. Recherche Framework pour traitement asynchrone
    Par kisitomomotene dans le forum Langages de programmation
    Réponses: 2
    Dernier message: 02/06/2008, 18h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo