Aidez-moi à utiliser "PHP Parallel" dans mon Code suivant

Eléphant du PHP | 137 Messages

12 juin 2022, 04:29

Bonjour.

Je souhaiterais utiliser PHP-8 Parallel (https://github.com/krakjoe/parallel. Ou encore: https://php.net/parallel) dans ma fonction follow_links:

Code : Tout sélectionner

function followLinks($urls) { global $alreadyCrawled; global $crawling; $parser = new DomDocumentParser($page); foreach($urls as $page) { $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; // Output the page title, descriptions, keywords, URL, Image, Video, etc... This output is // piped off to an external file using the command line. getDetails($href); } } } // Remove an item from the array after we have crawled it. // This prevents infinitely crawling the same page. array_shift($crawling); followLinks($crawling); } $starts = ["https://website1.dn", "https://website2.dn", "https://website3.dn", "https://website4.dn"]; followLinks($starts);
Je cherche donc à traiter tous les URLs stockés dans la variable $starts à la fois de façon parallèle sachant que c'est la fonction get_details qui récupère les données de chaque URL ???

Merci de m'aider.
Modifié en dernier par chegmarco le 12 juin 2022, 15:22, modifié 1 fois.

Eléphant du PHP | 137 Messages

12 juin 2022, 15:22

Voici ce que j'ai essayé de faire:

Code : Tout sélectionner

function followLinks($urls) { global $alreadyCrawled; global $crawling; $parser = new DomDocumentParser($page); foreach($urls as $page) { $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; $runtime = new \parallel\Runtime(); $crawling_arr_length = count($crawling); $future = $runtime->run(function() { for ($i=0; $i < $crawling_arr_length; $i++) // Output the page title, descriptions, keywords, URL, Image, Video, etc... This output is // piped off to an external file using the command line. getDetails($href); return "easy"; }); } } } // Remove an item from the array after we have crawled it. // This prevents infinitely crawling the same page. array_shift($crawling); followLinks($crawling); } $starts = ["https://website1.dn", "https://website2.dn", "https://website3.dn", "https://website4.dn"]; followLinks($starts);
Vous pouvez constater de la ligne 24 à 33 que j'ai essayé d'inclure le classe Runtime instanciée $runtime = new \parallel\Runtime(); mais, c'est complètement brouillon et ne fonctionne pas.

Quel serait la manière la plus appropriée pour inclure le Parallel dans l'appel de ma fonction getDetails dans la fonction followLinks ???

Avatar du membre
Eléphanteau du PHP | 41 Messages

13 juin 2022, 12:08

je pose juste quelques questions imbriqué :) :
-1 ton code fait quoi et il doit faire quoi
-2 et pourquoi tu veux faire du parallèle ?

je te dis cela par ce qu'en général dans 99% des cas on en a pas besoin. mais comme je ne sais pas le pourquoi du comment.
déjà ça pourrait être une bonne piste pour t'aider.
ça serait con de faire du parallèle et dans 1 semaine de t'apercevoir qu'il y a mieux et que tu en avais pas besoin.

Avatar du membre
Eléphanteau du PHP | 41 Messages

13 juin 2022, 14:16

du coup j'ai posé des questions plus haut mais je vais te répondre au sujet de paralléle :
tous est dans l'exemple sur leurs github https://github.com/krakjoe/parallel
$runtime = new \parallel\Runtime();

$future = $runtime->run(function(){
    for ($i = 0; $i < 500; $i++)
        echo "*";

    return "easy";
});

for ($i = 0; $i < 500; $i++) {
    echo ".";
}

printf("\nUsing \\parallel\\Runtime is %s\n", $future->value());

mais si tu regarde bien avant : tu as

Requirements and Installation
See INSTALL.md <--


et tu as du sauté cette étape et oui ce genre de contexte n'est pas sans quelques épines dans le pied.
si tu as un début de niveau en PHP et que tu cherche à level UP je te conseil de passé beaucoup de temps à tester / comprendre et faire fonctionné. en définitive quasiment 90% des problématique passent par les même étapes et le plus chiant c'est les outils qui facilite la vie sans explication d'utilisation ;)

mais bon c'est la vie

donc tu aura besoin de :

Requirements

PHP 8.0 <-- ça ne dit pas que 8.1 ou supérieur ça fonctionnera donc c'est problématique
ZTS
<pthread.h>

et bien c'est ma barré pour toi
je ne sais pas si tu es sous linux
si c'est le cas tu as de forte chance d'avoir la dernier version de Pthread pour php c'est un librérie génial
et sous windows je ne sais pas il faudrait la compilé là c'est un cran au dessus ou trouvé une personne sur github ou le net qui l'a déjà compilé pour l'utilisé.
à parti de là tu pourras l'utilisé.
perso ça fait un moment que je ne compile plus les derniers version de pthread les versions que j'ai sont que en php 7.3 ou 7.4.


bref dans tout les cas de figure il te manque cette librérie Pthread et malheureusement je pense une version PHP qui sera compiler spécifiquement pour le support de Pthread

https://www.php.net/manual/fr/pthreads.requirements.php
le fameu ZTS Zend Thread Safety
probablement un option à activé quand on compile l'executable (on fabrique une version compatible)

:( franchement c'est avancé pas puissant mais chiant à mettre en œuvre quand on ne connais pas.
mais maintenant après l'avoir fait des mois je ne saurais te dire là si je suis à ta place combien de temps ça me prendrait.
je pense quelques jours pour tout mettre convenablement en place au préalable pour une compilations. Mais je suis sous windows . coup classique sous linux c'est rapide; un apt-get PHP8 en source
tu récupère les lignes qui lance la compilation PHP 8 avec les options --enable-ZTS un truc comme ça et cette premier étape est fini puis il faudra au ajouté le projet Pthread pour qu'il compile aussi celui-ci :)
et aprés ça il faudra tester Pthread mais ce n'est que le début du film d'horreur

aprés quelque temps à comprendre comme ça fonction là seulement tu pourras envisager de tester Paralléle qui exploite Pthread

Eléphant du PHP | 137 Messages

14 juin 2022, 02:29

je pose juste quelques questions imbriqué :) :
-1 ton code fait quoi et il doit faire quoi
-2 et pourquoi tu veux faire du parallèle ?

je te dis cela par ce qu'en général dans 99% des cas on en a pas besoin. mais comme je ne sais pas le pourquoi du comment.
déjà ça pourrait être une bonne piste pour t'aider.
ça serait con de faire du parallèle et dans 1 semaine de t'apercevoir qu'il y a mieux et que tu en avais pas besoin.
Merci pour votre réponse. Si vous voulez savoir ce que fait mon, c'est qu'il récupère les meta title et description (un petit scraper ou crawler) mais je voulais ajouter du parallèle pour accélérer le traitement et/ou la vitesse du scraping.

Autrement dit, je souhaiterais faire le scraping de tous les URLs en même temps.

Vous avez d'autres idée à me donner à part le fait de faire du parallèle ???

Avatar du membre
Eléphanteau du PHP | 41 Messages

14 juin 2022, 09:40

oui tu peux faire tourné autant d'instance de php que tu veux; je suis sous windows donc je me préparer parfois des dossiers de 4 à 8 php; et tous vont utilisé la dll Sqlite et la même base de donnée.
l'objectif serait de produire un hash de ton url et tu stock dans la base de donné Sqlite le hash | l'Url . et quand tu as produit le hash tu fait une recherche dans Sqlite si l'adresse n'existe pas déjà. pour gagner du temps. et évidement tu stock tout ce petit monde sur un SSD pour gagner en vitesse de lecture et d'écriture;
voila. évidement je peux aussi produire de temps en temps un mini listing des URL à évité et chaque Php va copier une version de se listing dans son dossier et savoir que s'il tombe sur cette url on va pas plus loin. voila tu as plein d'astuce. est ce que tu peux te retrouvé avec des doublons oui c'est une certitude mais ça se filtre par la suite. là les quelques idée vont viré les 80% de doublon que tu risque d'avoir. en plus si le hash est passé en clé unique donc déjà ça sera bloqué s'il y a doublon.

Eléphant du PHP | 137 Messages

14 juin 2022, 14:05

Merci pour l'idée. Pas mal comme idée. J'essaierai ça aussi.