Όσοι χρησιμοποιούν cURL μετά από ενημερώσεις στις 5.6.1, 5.5.17 αντιμετώπισαν το γεγονός ότι η λειτουργική μονάδα cURL σταμάτησε να λειτουργεί. Το πρόβλημα δεν έχει εξαφανιστεί από τότε. Ακόμη και στην τελευταία έκδοση της PHP 5.6.4, αυτό το πρόβλημα παρέμεινε.

Πώς ξέρετε εάν το cURL λειτουργεί για εσάς;

Δημιουργώ php αρχείοκαι αντιγράψτε εκεί:

Ανοίξτε το από τον διακομιστή. Αν η έξοδος είναι κάτι σαν:

Πίνακας ( => 468736 => 3 => 3997 => 0 => 7.39.0 => x86_64-pc-win32 => OpenSSL/1.0.1j => 1.2.7.3 => Πίνακας ( => dict => αρχείο => ftp => ftps => gopher => http => https => imap => imaps => ldap => pop3 => pop3s => rtsp => scp => sftp => smtp => smtps => telnet => tftp) )

Οπότε το cURL είναι εντάξει, αν είναι σφάλμα PHP, τότε υπάρχει πρόβλημα.

Πρώτα, φυσικά, ελέγξτε το αρχείο php.ini, βρείτε τη γραμμή εκεί

Επέκταση=php_curl.dll

Και βεβαιωθείτε ότι δεν έχει πριν από το ερωτηματικό.

Εάν συμβαίνει αυτό και το cURL δεν λειτουργεί, τότε μπορεί να πραγματοποιηθεί μια άλλη δοκιμή για να επιβεβαιωθεί η ασυνήθιστη κατάσταση. Δημιουργήστε ένα άλλο αρχείο php με περιεχόμενο:

Αναζητήστε το cURL στο πρόγραμμα περιήγησης, εάν υπάρχει μόνο μία αντιστοίχιση, τότε η μονάδα cURL δεν φορτώνεται:

Ταυτόχρονα, τόσο ο Apache όσο και η PHP λειτουργούν ως συνήθως.

Τρεις λύσεις:

  1. Μέθοδος 1 (όχι kosher). Εάν έχετε PHP 5.6.*, τότε πάρτε την έκδοση της PHP 5.6.0, από εκεί πάρτε το παλιό αρχείο php_curl.dll και αντικαταστήστε το με το νέο σας από την έκδοση, για παράδειγμα, PHP 5.6.4. Για όσους έχουν PHP 5.5.17 και άνω, πρέπει να λάβετε το ίδιο αρχείο από την PHP 5.5.16 και να το αντικαταστήσετε επίσης. Το μόνο πρόβλημα εδώ είναι να βρείτε αυτές τις παλιές εκδόσεις. Μπορείτε, φυσικά, να ρίξετε μια ματιά στο http://windows.php.net/downloads/snaps/php-5.6, αλλά προσωπικά δεν βρήκα αυτό που χρειαζόμουν εκεί. Και η ίδια η απόφαση κατά κάποιο τρόπο δεν είναι αρκετά kosher.
  2. Η δεύτερη μέθοδος (πολύ γρήγορη, αλλά και όχι kosher). Αντιγράψτε το αρχείο libssh2.dll από τον κατάλογο PHP στον κατάλογο Apache24bin και επανεκκινήστε τον Apache.
  3. Μέθοδος τρίτη (kosher - άνθρωποι kosher χειροκροτούν όρθιοι). Πρέπει να προσθέσετε το δικό σας Κατάλογος PHPστο PATH. Πώς να το κάνετε αυτό περιγράφεται πολύ καλά στην επίσημη τεκμηρίωση.

Ελέγχουμε:

Voila, η ενότητα cURL είναι στη θέση της.

Γιατί αυτό? Από πού προήλθε αυτό το πρόβλημα; Δεν υπάρχει απάντηση σε αυτό το ερώτημα, αν και ο μηχανισμός εμφάνισής του έχει ήδη περιγραφεί.

Το πρόβλημα φαίνεται να σχετίζεται με το γεγονός ότι η 5.6.1 υποτίθεται ότι θα κυκλοφορούσε με ένα ενημερωμένο libcurl 7.38.0. Αλλά αυτό δεν είναι γνωστό με βεβαιότητα, οι συντάκτες της PHP γνέφουν στον Apache, λέγοντας ότι υπάρχουν κάποια σφάλματα εκεί.

Ο μηχανισμός του προβλήματος: εάν το σύστημα PATH δεν περιλαμβάνεται Κατάλογος PHP, τότε όταν ξεκινά η υπηρεσία Apache, δεν μπορεί να βρει το νέο dll (libssh2.dll) που είναι μια εξάρτηση για το php_curl.

Σχετικές αναφορές σφαλμάτων:

Μοιραίο σφάλμα: Κλήση σε απροσδιόριστη συνάρτηση curl_multi_init() σε ...

Γενικά, υπήρχαν προβλήματα με το cURL στην PHP, φαίνεται, αν όχι πάντα, τότε πολύ συχνά. Κατά τη διαδικασία του γκουγκλάροντας το πρόβλημά μου, συνάντησα νήματα, μερικά από τα οποία ήταν πάνω από δώδεκα ετών.

Επιπλέον, το googling έδωσε μερικά ακόμη συμπεράσματα:

Υπάρχουν αρκετές "οδηγίες για ηλίθιους" στο Διαδίκτυο, στις οποίες λένε λεπτομερώς, με εικόνες, πώς να αποσχολιάσετε τη γραμμή extension=php_curl.dll στο αρχείο php.ini.

Στον επίσημο ιστότοπο της PHP, στην ενότητα για την εγκατάσταση του cURL, υπάρχουν μόνο δύο προτάσεις σχετικά με το σύστημα Windows:

Για να εργαστείτε με αυτήν την ενότητα στο αρχεία WindowsΤο libeay32.dll και το ssleay32.dll πρέπει να υπάρχουν στο σύστημα μεταβλητή περιβάλλοντοςΜΟΝΟΠΑΤΙ. Δεν χρειάζεστε το αρχείο libcurl.dll από τον ιστότοπο cURL.

Τα έχω διαβάσει δέκα φορές. Αλλαγή σε αγγλική γλώσσακαι να το διαβάσετε μερικές φορές στα αγγλικά. Κάθε φορά πείθομαι όλο και περισσότερο ότι αυτές οι δύο προτάσεις γράφτηκαν από ζώα, ή κάποιος απλώς πήδηξε στο πληκτρολόγιο - δεν καταλαβαίνω το νόημά τους.

Υπάρχουν επίσης μερικές τρελές συμβουλές και οδηγίες (κατάφερα να δοκιμάσω κιόλας).

Στον ιστότοπο αναφοράς σφαλμάτων PHP, έχω ήδη φτάσει κοντά στο να ξετυλίξω την ανάγκη να συμπεριλάβω τον κατάλογο με την PHP στη μεταβλητή συστήματος PATH.

Γενικά, για όσους έχουν πρόβλημα με το cURL και που πρέπει να «συμπεριλάβουν έναν κατάλογο με PHP στη μεταβλητή συστήματος PATH», μεταβείτε στην οδηγία που ήδη αναφέρθηκε παραπάνω http://php.net/manual/ru/faq.installation .php#faq .installation.addtopath . Όλα είναι απλά εκεί και, το πιο σημαντικό, αυτό που πρέπει να γίνει είναι γραμμένο στην ανθρώπινη γλώσσα.

Έχουμε: php 5.2.3, Windows XP, Apache 1.3.33
Πρόβλημα - η λειτουργική μονάδα cURL δεν ανιχνεύεται εάν η PHP εκτελείται από το Apache
Στο php.ini, το extension=php_curl.dll δεν σχολιάζεται, το extension_dir έχει οριστεί σωστά,
Το libeay32.dll και το ssleay32.dll αντιγράφονται στο c:\windows\system32.
Ωστόσο, η συνάρτηση phpinfo() δεν εμφανίζει τη λειτουργική μονάδα cURL μεταξύ των εγκατεστημένων και όταν ξεκινά ο Apache, τα ακόλουθα γράφονται στο αρχείο καταγραφής:

Εκκίνηση PHP: Δεν είναι δυνατή η φόρτωση της δυναμικής βιβλιοθήκης "c:/php/ext/php_curl.dll" - Δεν ήταν δυνατή η εύρεση της καθορισμένης λειτουργικής μονάδας.

Εάν τρέχετε php από γραμμή εντολών, τότε τα σενάρια που περιέχουν εντολές από το cURL λειτουργούν άψογα και εάν εκτελούνται από κάτω από τον Apache, δίνουν τα εξής:
Μοιραίο σφάλμα: Κλήση σε απροσδιόριστη συνάρτηση: curl_init() - και ανεξάρτητα από τον τρόπο εγκατάστασης της PHP - ως CGI ή ως λειτουργική μονάδα.

Στο Διαδίκτυο, συνάντησα επανειλημμένα μια περιγραφή αυτού του προβλήματος - ειδικά για τη μονάδα cURL, αλλά οι λύσεις που προτάθηκαν εκεί δεν βοηθούν. Και άλλαξα ήδη την PHP 5.2 σε PHP 5.2.3 - και πάλι δεν βοήθησε.

David Mzareulyan [ντοσιέ]
Έχω ένα php.ini - το έλεγξα ψάχνοντας στο δίσκο. Το γεγονός ότι χρησιμοποιείται το ίδιο php.ini επιβεβαιώνεται επίσης εύκολα από το γεγονός ότι οι αλλαγές που έγιναν σε αυτό επηρεάζουν τόσο την εκκίνηση των σεναρίων από κάτω από το Apache όσο και από τη γραμμή εντολών.

Ντανιήλ Ιβάνοφ [ντοσιέ] Καλύτερα να κάνετε ένα αρχείο με μια κλήση

και ανοίξτε το με πρόγραμμα περιήγησης.
Και μετά τρέξτε στην εντολή γραμμή php-i | grep ini και ελέγξτε τις διαδρομές προς το php.ini όπως τις βλέπει η php, όχι από την παρουσία του αρχείου στο δίσκο.

Ντανιήλ Ιβάνοφ [ντοσιέ] Τι βγάζει το php -i; Το προεπιλεγμένο δυαδικό αρχείο μπορεί να αναζητήσει τη διαμόρφωση αλλού, ανάλογα με τις επιλογές μεταγλώττισης. Δεν είναι η πρώτη φορά που συναντώ το γεγονός ότι τα mod_php.dll και php.exe βλέπουν διαφορετικά αρχεία ini και αυτό που λειτουργεί στο ένα δεν λειτουργεί στο άλλο.

Βασίλι Σβιρίντοφ [ντοσιέ]
Το php -i παράγει τα εξής:

Αρχείο Διαμόρφωσης (php.ini) Διαδρομή => C:\WINDOWS
Φορτωμένο αρχείο διαμόρφωσης => C:\PHP\php.ini

Μετακίνηση του αρχείου php.ini σε έναν κατάλογο καταστάσεις Windowsδεν αλλάζει.

Ντανιήλ Ιβάνοφ [ντοσιέ]
Τι θα λέγατε για τις υπόλοιπες ενότητες; Για παράδειγμα php_mysql;;; Συνδετικός? Ή μήπως απλώς το cURL είναι τόσο άσχημο;

Χμ, ούτε σε εμένα φορτώνει... Σε πολύ διαφορετική διαμόρφωση (Apache 2.2 συν PHP 5.1.6 κάτω από το Zend Studio). Αλλά δεν είναι αυτό το θέμα. Ένα πείραμα με την εκτέλεση του Apache από τη γραμμή εντολών (ακριβέστερα από το FAR) έδειξε κάτι ενδιαφέρον. Χωρίς να προσπαθήσετε να συνδέσετε τον Kurl - όλα ξεκινούν σε μια δέσμη. Όταν προσπαθείτε να συνδέσετε το Kurl δίνει ένα σφάλμα στο ... php5ts.dll.

Γειά σου!
Είχα παρόμοιο πρόβλημα, έψαχνα πολύ καιρό να βρω λύση, βάλε κι άλλα νέα έκδοση PHP, βρήκε τελικά αυτό το φόρουμ. Δεν υπήρχε λύση εδώ, οπότε προσπάθησα περισσότερο ο ίδιος.

Έφτιαξα ένα zend studio για μένα, και πριν από αυτό υπήρχε μια παλαιότερη έκδοση της PHP. Ίσως ένας από αυτούς εγκατέστησε τις βιβλιοθήκες του και παρέμειναν εκεί - ξεπερασμένοι.

Ευχαριστώ για τις συμβουλές, ειδικά το τελευταίο από το "Nehxby". Μπήκα στο C:\windows\system32 και διαπίστωσα ότι οι βιβλιοθήκες libeay32.dll και ssleay32.dll δεν έχουν το ίδιο μέγεθος με τις αρχικές. Εγκατέστησα το memcached, ίσως μετά. Έτσι, αν προσθέσατε chot, πηγαίνετε στο system32 :)

είχε το ίδιο πρόβλημα, χρησιμοποίησε την εντολή php -i | grep ini
έδειξε ότι λείπει η βιβλιοθήκη zlib1.dll
ήταν στο φάκελο με Apache, έγραψα ένα αντίγραφο στο φάκελο με PHP
Επανέλαβα την εντολή, έδειξε ότι η βιβλιοθήκη zlib.dll δεν ήταν αρκετή, την έγραψα στον φάκελο Apache και όλα δούλεψαν.
και όλες οι βιβλιοθήκες ήταν επίσης php5ts.dll, οπότε σκεφτείτε την παρουσία όλων των απαραίτητων βιβλιοθηκών.

Αποφάσισε να προσθέσει. Γιατί και εγώ αντιμετώπισα αυτό το πρόβλημα. Βρήκα αυτό το φόρουμ μέσω ενός συνδέσμου σε άλλο ιστότοπο. Γενικά, όλες οι προτεινόμενες επιλογές δεν είναι παρά πατερίτσες. η ουσία της λύσης στα Windows. πρέπει να ορίσετε τη μεταβλητή PATH. προσδιορίζοντας πού έχετε PHP. και το Hallelujah curl δεν πετάει κανένα λάθος. όπως και άλλες βιβλιοθήκες...

Το cURL είναι ένα ειδικό εργαλείο που έχει σχεδιαστεί για τη μεταφορά αρχείων και δεδομένων χρησιμοποιώντας τη σύνταξη URL. Αυτή η τεχνολογίαυποστηρίζει πολλά πρωτόκολλα όπως HTTP, FTP, TELNET και πολλά άλλα. Το cURL σχεδιάστηκε αρχικά για να είναι ένα εργαλείο γραμμής εντολών. Ευτυχώς για εμάς, η βιβλιοθήκη cURL υποστηρίζεται από τη γλώσσα Προγραμματισμός PHP. Σε αυτό το άρθρο, θα δούμε μερικές από τις προηγμένες δυνατότητες του cURL, καθώς και θα αγγίξουμε πρακτική χρήσηαπέκτησε γνώση μέσω PHP.

Γιατί cURL;

Στην πραγματικότητα, είναι πολλά εναλλακτικούς τρόπουςλήψη του περιεχομένου μιας ιστοσελίδας. Σε πολλές περιπτώσεις, κυρίως από τεμπελιά, έχω χρησιμοποιήσει απλά Συναρτήσεις PHPαντί για cURL:

$content = file_get_contents("http://www.nettuts.com"); // ή $lines = αρχείο ("http://www.nettuts.com"); // ή readfile("http://www.nettuts.com");

Ωστόσο, αυτές οι λειτουργίες δεν έχουν ουσιαστικά καμία ευελιξία και περιέχουν τεράστιο αριθμό ελλείψεων όσον αφορά τον χειρισμό σφαλμάτων και ούτω καθεξής. Επιπλέον, υπάρχουν ορισμένες εργασίες που απλά δεν μπορείτε να επιλύσετε με αυτές τις τυπικές λειτουργίες: αλληλεπίδραση με cookies, έλεγχος ταυτότητας, υποβολή φόρμας, μεταφόρτωση αρχείων και ούτω καθεξής.

Το cURL είναι μια ισχυρή βιβλιοθήκη που υποστηρίζει πολλά διαφορετικά πρωτόκολλα, επιλογές και παρέχει λεπτομερείς πληροφορίεςσχετικά με τα αιτήματα URL.

Βασική Δομή

  • Αρχικοποίηση
  • Εκχώρηση παραμέτρων
  • Εκτέλεση και λήψη του αποτελέσματος
  • Απελευθέρωση μνήμης

// 1. αρχικοποίηση $ch = curl_init(); // 2. καθορίστε επιλογές, συμπεριλαμβανομένου του url curl_setopt($ch, CURLOPT_URL, "http://www.nettuts.com"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 0); // 3. λάβετε HTML ως αποτέλεσμα $output = curl_exec($ch); // 4. κλείστε τη σύνδεση curl_close($ch);

Το βήμα #2 (δηλαδή, η κλήση curl_setopt()) θα συζητηθεί σε αυτό το άρθρο πολύ περισσότερο από όλα τα άλλα βήματα, επειδή. σε αυτό το στάδιο, συμβαίνουν όλα τα πιο ενδιαφέροντα και χρήσιμα πράγματα που πρέπει να γνωρίζετε. Υπάρχει ένας τεράστιος αριθμός διαφορετικών επιλογών στο cURL που πρέπει να καθοριστούν για να μπορέσετε να διαμορφώσετε ένα αίτημα URL με τον πιο εμπεριστατωμένο τρόπο. Δεν θα εξετάσουμε ολόκληρη τη λίστα ως σύνολο, αλλά θα επικεντρωθούμε μόνο σε αυτά που θεωρώ απαραίτητα και χρήσιμα για αυτό το μάθημα. Όλα τα άλλα μπορείτε να εξερευνήσετε μόνοι σας εάν αυτό το θέμα σας ενδιαφέρει.

Έλεγχος σφαλμάτων

Επιπλέον, μπορείτε επίσης να χρησιμοποιήσετε δηλώσεις υπό όρουςγια να ελέγξετε αν η λειτουργία ήταν επιτυχής:

// ... $output = curl_exec($ch); if ($output === FALSE) ( echo "cURL Error: " . curl_error($ch); ) // ...

Εδώ σας ζητώ να σημειώσετε πολύ σημαντικό σημείο: θα πρέπει να χρησιμοποιήσουμε "=== false" για σύγκριση, αντί για "== false". Για όσους δεν γνωρίζουν, αυτό θα μας βοηθήσει να διακρίνουμε μεταξύ ενός κενού αποτελέσματος και μιας ψευδούς δυαδικής τιμής, η οποία θα υποδεικνύει σφάλμα.

Λήψη των πληροφοριών

Ένα άλλο επιπλέον βήμα είναι να λάβετε δεδομένα σχετικά με το αίτημα cURL μετά την εκτέλεσή του.

// ... curl_exec($ch); $πληροφορίες = curl_getinfo($ch); ηχώ "Πήρε" . $info["total_time"] . " δευτερόλεπτα για το url " . $info["url"]; //...

Ο πίνακας που επιστράφηκε περιέχει τις ακόλουθες πληροφορίες:

  • "url"
  • "Τύπος περιεχομένου"
  • http_code
  • "header_size"
  • "request_size"
  • "χρόνος αρχείου"
  • "ssl_verify_result"
  • "redirect_count"
  • "συνολικός χρόνος"
  • "namelookup_time"
  • "connect_time"
  • "pretransfer_time"
  • "size_upload"
  • μέγεθος_λήψης
  • "speed_download"
  • "speed_upload"
  • "download_content_length"
  • "upload_content_length"
  • "starttransfer_time"
  • "redirect_time"

Ανίχνευση ανακατεύθυνσης ανάλογα με το πρόγραμμα περιήγησης

Σε αυτό το πρώτο παράδειγμα, θα γράψουμε κώδικα που μπορεί να ανιχνεύσει ανακατευθύνσεις URL βάσει διάφορες ρυθμίσειςπρόγραμμα περιήγησης. Για παράδειγμα, ορισμένοι ιστότοποι ανακατευθύνουν προγράμματα περιήγησης κινητό τηλέφωνο, ή οποιαδήποτε άλλη συσκευή.

Θα χρησιμοποιήσουμε την επιλογή CURLOPT_HTTPHEADER για να προσδιορίσουμε τις εξερχόμενες κεφαλίδες HTTP, συμπεριλαμβανομένου του ονόματος προγράμματος περιήγησης του χρήστη και των διαθέσιμων γλωσσών. Τελικά, θα είμαστε σε θέση να προσδιορίσουμε ποιοι ιστότοποι μας ανακατευθύνουν σε διαφορετικές διευθύνσεις URL.

// δοκιμαστική διεύθυνση URL $urls = array("http://www.cnn.com", "http://www.mozilla.com", "http://www.facebook.com"); // δοκιμή προγραμμάτων περιήγησης $browsers = array("standard" => array ("user_agent" => "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5 .6 (.NET CLR 3.5.30729)", "language" => "en-us,en;q=0.5"), "iphone" => πίνακας ("user_agent" => "Mozilla/5.0 (iPhone; U ; CPU όπως Mac OS X; en) AppleWebKit/420+ (KHTML, όπως Gecko) Έκδοση/3.0 Mobile/1A537a Safari/419.3", "language" => "en"), "γαλλικά" => πίνακας ("user_agent" => "Mozilla/4.0 (συμβατό; MSIE 7.0; Windows NT 5.1; GTB6; .NET CLR 2.0.50727)", "language" => "fr,fr-FR;q=0.5")); foreach ($urls ως $url) ( echo "URL: $url\n"; foreach ($browsers ως $test_name => $browser) ( $ch = curl_init(); // προσδιορίστε τη διεύθυνση url curl_setopt($ch, CURLOPT_URL, $url); // ορισμός κεφαλίδων προγράμματος περιήγησης curl_setopt($ch, CURLOPT_HTTPHEADER, array("User-Agent: ($browser["user_agent"])", "Accept-Language: ($browser["language"])" ) ); // δεν χρειαζόμαστε περιεχόμενο σελίδας curl_setopt($ch, CURLOPT_NOBODY, 1); // πρέπει να λάβουμε κεφαλίδες HTTP curl_setopt($ch, CURLOPT_HEADER, 1); // επιστρέφουμε αποτελέσματα αντί για έξοδο curl_setopt($ch , CURLOPT_RETURNTRANSFER, 1); $output = curl_exec($ch); curl_close($ch); // Υπήρχε ανακατεύθυνση HTTP; if (preg_match("!Τοποθεσία: (.*)!", $output, $matches) ) ( echo " $test_name: ανακατευθύνει σε $matches\n"; ) else ( echo "$test_name: χωρίς ανακατεύθυνση\n"; ) ) echo "\n\n"; )

Αρχικά, καθορίζουμε μια λίστα με διευθύνσεις URL των τοποθεσιών που θα ελέγξουμε. Πιο συγκεκριμένα, χρειαζόμαστε τις διευθύνσεις αυτών των τοποθεσιών. Στη συνέχεια, πρέπει να ορίσουμε τις ρυθμίσεις του προγράμματος περιήγησης για να δοκιμάσουμε καθεμία από αυτές τις διευθύνσεις URL. Μετά από αυτό, θα χρησιμοποιήσουμε έναν βρόχο στον οποίο θα εκτελέσουμε όλα τα αποτελέσματα που ελήφθησαν.

Το κόλπο που χρησιμοποιούμε σε αυτό το παράδειγμα για να ορίσουμε Ρυθμίσεις cURL, θα μας επιτρέψει να λάβουμε όχι το περιεχόμενο της σελίδας, αλλά μόνο τις κεφαλίδες HTTP (αποθηκευμένες στο $output). Στη συνέχεια, χρησιμοποιώντας ένα απλό regex, μπορούμε να προσδιορίσουμε εάν η συμβολοσειρά "Location:" υπήρχε στις κεφαλίδες που λάβαμε.

Όταν εκτελείτε αυτόν τον κώδικα, θα πρέπει να λάβετε κάτι σαν αυτό:

Υποβολή αιτήματος POST σε μια συγκεκριμένη διεύθυνση URL

Όταν σχηματίζετε ένα αίτημα GET, τα μεταδιδόμενα δεδομένα μπορούν να μεταβιβαστούν στη διεύθυνση URL μέσω μιας "συμβολοσειράς ερωτήματος". Για παράδειγμα, όταν κάνετε μια αναζήτηση στο Google, οι όροι αναζήτησης βρίσκονται στο γραμμή διεύθυνσηςνέα διεύθυνση URL:

http://www.google.com/search?q=ruseller

Δεν χρειάζεται να χρησιμοποιήσετε το cURL για να προσομοιώσετε αυτό το αίτημα. Αν τελικά σας ξεπεράσει η τεμπελιά, χρησιμοποιήστε τη συνάρτηση "file_get_contents ()" για να έχετε το αποτέλεσμα.

Αλλά το θέμα είναι ότι ορισμένες φόρμες HTML στέλνουν αιτήματα POST. Τα δεδομένα αυτών των φορμών μεταφέρονται μέσω του σώματος του αιτήματος HTTP και όχι όπως στην προηγούμενη περίπτωση. Για παράδειγμα, εάν συμπληρώσατε μια φόρμα σε ένα φόρουμ και κάνετε κλικ στο κουμπί αναζήτησης, τότε πιθανότατα θα γίνει ένα αίτημα POST:

http://codeigniter.com/forums/do_search/

Μπορούμε να γράψουμε Σενάριο PHP, το οποίο μπορεί να μιμηθεί αυτού του είδους τη διεύθυνση URL αιτήματος. Αρχικά, ας δημιουργήσουμε ένα απλό αρχείο για αποδοχή και εμφάνιση δεδομένων POST. Ας το ονομάσουμε post_output.php:

Print_r($_POST);

Στη συνέχεια δημιουργούμε ένα σενάριο PHP για να εκτελέσουμε το αίτημα cURL:

$url = "http://localhost/post_output.php"; $post_data = array("foo" => "bar", "query" => "Nettuts", "action" => "Υποβολή"); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // υποδεικνύουν ότι έχουμε ένα αίτημα POST curl_setopt($ch, CURLOPT_POST, 1); // προσθήκη μεταβλητών curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); $output = curl_exec($ch); curl_close($ch); echo $output;

Όταν εκτελείτε αυτό το σενάριο, θα πρέπει να έχετε ένα παρόμοιο αποτέλεσμα:

Έτσι, το αίτημα POST στάλθηκε στο σενάριο post_output.php, το οποίο με τη σειρά του έβγαλε τον υπερσφαιρικό πίνακα $_POST, τα περιεχόμενα του οποίου λάβαμε χρησιμοποιώντας το cURL.

Ανέβασμα αρχείου

Αρχικά, ας δημιουργήσουμε ένα αρχείο για να το σχηματίσουμε και να το στείλουμε στο αρχείο upload_output.php:

Print_r($_FILES);

Και εδώ είναι ο κώδικας σεναρίου που εκτελεί την παραπάνω λειτουργία:

$url = "http://localhost/upload_output.php"; $post_data = πίνακας ("foo" => "bar", // αρχείο για μεταφόρτωση "upload" => "@C:/wamp/www/test.zip"); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); $output = curl_exec($ch); curl_close($ch); echo $output;

Όταν θέλετε να ανεβάσετε ένα αρχείο, το μόνο που έχετε να κάνετε είναι να το ανεβάσετε ως συνήθως μεταβλητή ανάρτησης, τοποθετώντας το σύμβολο @ μπροστά του. Όταν εκτελείτε το γραπτό σενάριο, θα λάβετε το ακόλουθο αποτέλεσμα:

Πολλαπλές cURL

Ενα από τα πολλά δυνάμειςΤο cURL είναι η δυνατότητα δημιουργίας "πολλαπλών" χειριστών cURL. Αυτό σας επιτρέπει να ανοίξετε μια σύνδεση σε πολλές διευθύνσεις URL ταυτόχρονα και ασύγχρονα.

Στην κλασική έκδοση του αιτήματος cURL, η εκτέλεση του σεναρίου αναστέλλεται και αναμένεται να ολοκληρωθεί η λειτουργία αιτήματος URL, μετά την οποία το σενάριο μπορεί να συνεχιστεί. Εάν σκοπεύετε να αλληλεπιδράσετε με πάρα πολλές διευθύνσεις URL, αυτό θα είναι αρκετά χρονοβόρο, καθώς στην κλασική περίπτωση μπορείτε να εργαστείτε μόνο με μία διεύθυνση URL τη φορά. Ωστόσο, μπορούμε να διορθώσουμε αυτήν την κατάσταση χρησιμοποιώντας ειδικούς χειριστές.

Ας ρίξουμε μια ματιά στο παράδειγμα κώδικα που πήρα από το php.net:

// δημιουργία μερικών πόρων cURL $ch1 = curl_init(); $ch2 = curl_init(); // καθορίστε τη διεύθυνση URL και άλλες παραμέτρους curl_setopt($ch1, CURLOPT_URL, "http://lxr.php.net/"); curl_setopt($ch1, CURLOPT_HEADER, 0); curl_setopt($ch2, CURLOPT_URL, "http://www.php.net/"); curl_setopt($ch2, CURLOPT_HEADER, 0); //δημιουργία ενός πολλαπλού χειριστή cURL $mh = curl_multi_init(); //προσθήκη πολλαπλών χειριστών curl_multi_add_handle($mh,$ch1); curl_multi_add_handle($mh,$ch2); $active = null; //εκτέλεση ($mrc = curl_multi_exec($mh, $active); ) ενώ ($mrc == CURLM_CALL_MULTI_PERFORM); ενώ ($active && $mrc‎ == CURLM_OK) ( if (curl_multi_select($mh) != -1) ( do ( $mrc‎ = curl_multi_exec($mh, $active); ) ενώ ($mrc == CURLM_CALL_MULTI_PERFORM); ) ) //close curl_multi_remove_handle($mh, $ch1); curl_multi_remove_handle($mh, $ch2); curl_multi_close($mh);

Η ιδέα είναι ότι μπορείτε να χρησιμοποιήσετε πολλαπλούς χειριστές cURL. Χρησιμοποιώντας έναν απλό βρόχο, μπορείτε να παρακολουθείτε ποια αιτήματα δεν έχουν ακόμη ολοκληρωθεί.

Σε αυτό το παράδειγμα, υπάρχουν δύο κύριοι βρόχοι. Ο πρώτος βρόχος do-while καλεί τη συνάρτηση curl_multi_exec(). Αυτή η δυνατότητα δεν εμποδίζει. Εκτελείται όσο πιο γρήγορα μπορεί και επιστρέφει την κατάσταση του αιτήματος. Εφόσον η επιστρεφόμενη τιμή είναι η σταθερά "CURLM_CALL_MULTI_PERFORM", αυτό σημαίνει ότι η εργασία δεν έχει ακόμη ολοκληρωθεί (για παράδειγμα, σε αυτή τη στιγμήΟι κεφαλίδες http αποστέλλονται στη διεύθυνση URL). Γι' αυτό συνεχίζουμε να ελέγχουμε αυτήν την τιμή επιστροφής μέχρι να έχουμε διαφορετικό αποτέλεσμα.

Στον επόμενο βρόχο, ελέγχουμε τη συνθήκη ενώ $active = "true". Είναι η δεύτερη παράμετρος της συνάρτησης curl_multi_exec(). Η τιμή αυτής της μεταβλητής θα είναι "true" όσο οποιαδήποτε από τις υπάρχουσες αλλαγές είναι ενεργή. Στη συνέχεια, καλούμε τη συνάρτηση curl_multi_select(). Η εκτέλεσή του «μπλοκάρει» εφόσον υπάρχει τουλάχιστον μία ενεργή σύνδεση, μέχρι να ληφθεί απάντηση. Όταν συμβεί αυτό, επιστρέφουμε στον κύριο βρόχο για να συνεχίσουμε να εκτελούμε αιτήματα.

Και τώρα ας εφαρμόσουμε όσα μάθαμε με ένα παράδειγμα που θα είναι πραγματικά χρήσιμο για μεγάλο αριθμό ανθρώπων.

Έλεγχος συνδέσμων στο WordPress

Φανταστείτε ένα blog με τεράστιο ποσόαναρτήσεις και μηνύματα, καθένα από τα οποία περιέχει συνδέσμους προς εξωτερικούς πόρους του Διαδικτύου. Ορισμένοι από αυτούς τους συνδέσμους ενδέχεται να είναι ήδη "νεκροί" για διάφορους λόγους. Ίσως η σελίδα έχει διαγραφεί ή ο ιστότοπος δεν λειτουργεί καθόλου.

Θα δημιουργήσουμε ένα σενάριο που θα αναλύει όλους τους συνδέσμους και θα βρίσκει ιστότοπους που δεν φορτώνονται και 404 σελίδες και στη συνέχεια θα μας παρέχει μια πολύ λεπτομερή αναφορά.

Θα πω αμέσως ότι αυτό δεν είναι παράδειγμα δημιουργίας πρόσθετου για WordPress. Αυτό είναι σχεδόν όλα ένα καλό πεδίο δοκιμών για εμάς.

Ας ξεκινήσουμε επιτέλους. Πρώτα πρέπει να ανακτήσουμε όλους τους συνδέσμους από τη βάση δεδομένων:

// διαμόρφωση $db_host = "localhost"; $db_user = "root"; $db_pass = ""; $db_name = "wordpress"; $excluded_domains = array("localhost", "www.mydomain.com"); $max_connections = 10; // αρχικοποίηση μεταβλητής $url_list = array(); $working_urls = array(); $dead_urls = array(); $not_found_urls = array(); $active = null; // συνδεθείτε στο MySQL if (!mysql_connect($db_host, $db_user, $db_pass)) ( die("Δεν ήταν δυνατή η σύνδεση: " . mysql_error()); ) if (!mysql_select_db($db_name)) ( die("Could όχι επιλέξτε db: " . mysql_error()); ) // επιλέξτε όλες τις δημοσιευμένες αναρτήσεις με συνδέσμους $q = "ΕΠΙΛΟΓΗ post_content ΑΠΟ wp_posts ΟΠΟΥ post_content LIKE "%href=%" AND post_status = "publish" AND post_type = "post "" ; $r = mysql_query($q) ή die(mysql_error()); ενώ ($d = mysql_fetch_assoc($r)) ( // ανάκτηση συνδέσμων χρησιμοποιώντας κανονικές εκφράσεις if (preg_match_all("!href=\"(.*?)\"!", $d["post_content"], $matches)) ( foreach ($ταιριάζει ως $url) ( $tmp = parse_url($url) ; if (in_array($tmp["host"], $excluded_domains)) (συνέχεια; ) $url_list = $url; ) ) ) // αφαιρέστε τα διπλότυπα $url_list = array_values(array_unique($url_list)); if (!$url_list) ( die("Δεν υπάρχει URL για έλεγχο"); )

Αρχικά, δημιουργούμε δεδομένα διαμόρφωσης για την αλληλεπίδραση με τη βάση δεδομένων και, στη συνέχεια, γράφουμε μια λίστα τομέων που δεν θα συμμετέχουν στον έλεγχο ($excluded_domains). Ορίζουμε επίσης έναν αριθμό που χαρακτηρίζει τον αριθμό των μέγιστων ταυτόχρονων συνδέσεων που θα χρησιμοποιήσουμε στο σενάριό μας ($max_connections). Στη συνέχεια, ενώνουμε τη βάση δεδομένων, επιλέγουμε τις αναρτήσεις που περιέχουν συνδέσμους και τις συγκεντρώνουμε σε έναν πίνακα ($url_list).

Ο παρακάτω κώδικας είναι λίγο περίπλοκος, επομένως κατανοήστε τον από την αρχή μέχρι το τέλος:

// 1. πολλαπλός χειριστής $mh = curl_multi_init(); // 2. προσθέστε πολλές διευθύνσεις URL για ($i = 0; $i< $max_connections; $i++) { add_url_to_multi_handle($mh, $url_list); } // 3. инициализация выполнения do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); // 4. основной цикл while ($active && $mrc == CURLM_OK) { // 5. если всё прошло успешно if (curl_multi_select($mh) != -1) { // 6. делаем дело do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); // 7. если есть инфа? if ($mhinfo = curl_multi_info_read($mh)) { // это значит, что запрос завершился // 8. извлекаем инфу $chinfo = curl_getinfo($mhinfo["handle"]); // 9. мёртвая ссылка? if (!$chinfo["http_code"]) { $dead_urls = $chinfo["url"]; // 10. 404? } else if ($chinfo["http_code"] == 404) { $not_found_urls = $chinfo["url"]; // 11. рабочая } else { $working_urls = $chinfo["url"]; } // 12. чистим за собой curl_multi_remove_handle($mh, $mhinfo["handle"]); // в случае зацикливания, закомментируйте данный вызов curl_close($mhinfo["handle"]); // 13. добавляем новый url и продолжаем работу if (add_url_to_multi_handle($mh, $url_list)) { do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); } } } } // 14. завершение curl_multi_close($mh); echo "==Dead URLs==\n"; echo implode("\n",$dead_urls) . "\n\n"; echo "==404 URLs==\n"; echo implode("\n",$not_found_urls) . "\n\n"; echo "==Working URLs==\n"; echo implode("\n",$working_urls); function add_url_to_multi_handle($mh, $url_list) { static $index = 0; // если у нас есть ещё url, которые нужно достать if ($url_list[$index]) { // новый curl обработчик $ch = curl_init(); // указываем url curl_setopt($ch, CURLOPT_URL, $url_list[$index]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_NOBODY, 1); curl_multi_add_handle($mh, $ch); // переходим на следующий url $index++; return true; } else { // добавление новых URL завершено return false; } }

Εδώ θα προσπαθήσω να τα βάλω όλα στα ράφια. Οι αριθμοί στη λίστα αντιστοιχούν στους αριθμούς στο σχόλιο.

  1. 1. Δημιουργήστε έναν πολλαπλό χειριστή.
  2. 2. Θα γράψουμε τη συνάρτηση add_url_to_multi_handle() λίγο αργότερα. Κάθε φορά που καλείται, μια νέα διεύθυνση url θα υποβάλλεται σε επεξεργασία. Αρχικά, προσθέτουμε 10 ($max_connections) διευθύνσεις URL.
  3. 3. Για να ξεκινήσουμε, πρέπει να εκτελέσουμε τη συνάρτηση curl_multi_exec(). Εφόσον επιστρέφει CURLM_CALL_MULTI_PERFORM, έχουμε ακόμα λίγη δουλειά να κάνουμε. Αυτό το χρειαζόμαστε κυρίως για να δημιουργήσουμε συνδέσεις.
  4. 4. Ακολουθεί ο κύριος βρόχος, ο οποίος θα εκτελεστεί εφόσον έχουμε τουλάχιστον μία ενεργή σύνδεση.
  5. 5. Η curl_multi_select() βρίσκεται σε αναμονή για την ολοκλήρωση της αναζήτησης URL.
  6. 6. Για άλλη μια φορά, πρέπει να πάρουμε το cURL για να κάνουμε κάποια δουλειά, δηλαδή να ανακτήσουμε τα επιστρεφόμενα δεδομένα απόκρισης.
  7. 7. Οι πληροφορίες επαληθεύονται εδώ. Ως αποτέλεσμα του αιτήματος, ένας πίνακας θα επιστραφεί.
  8. 8. Ο πίνακας που επιστράφηκε περιέχει ένα πρόγραμμα χειρισμού cURL. Αυτό θα χρησιμοποιήσουμε για να ανακτήσουμε πληροφορίες σχετικά με ένα συγκεκριμένο αίτημα cURL.
  9. 9. Εάν ο σύνδεσμος ήταν νεκρός ή το σενάριο έληξε, τότε δεν πρέπει να αναζητήσουμε κανένα κώδικας httpΕΝΑ;
  10. 10. Εάν ο σύνδεσμος μας επέστρεψε μια σελίδα 404, τότε ο κώδικας http θα περιέχει την τιμή 404.
  11. 11. Διαφορετικά, έχουμε έναν σύνδεσμο εργασίας μπροστά μας. (Μπορείτε να προσθέσετε πρόσθετους ελέγχους για κωδικό σφάλματος 500, κ.λπ.).
  12. 12. Στη συνέχεια, αφαιρούμε τον χειριστή cURL επειδή δεν τον χρειαζόμαστε πια.
  13. 13. Τώρα μπορούμε να προσθέσουμε ένα άλλο url και να εκτελέσουμε όλα όσα μιλήσαμε πριν.
  14. 14. Σε αυτό το βήμα, το σενάριο τελειώνει την εργασία του. Μπορούμε να αφαιρέσουμε όλα όσα δεν χρειαζόμαστε και να δημιουργήσουμε μια αναφορά.
  15. 15. Στο τέλος, θα γράψουμε μια συνάρτηση που θα προσθέσει ένα url στον χειριστή. Η στατική μεταβλητή $index θα αυξάνεται κάθε φορά δεδομένη λειτουργίαθα κληθεί.

Χρησιμοποίησα αυτό το σενάριο στο ιστολόγιό μου (με ορισμένους κατεστραμμένους συνδέσμους που προστέθηκαν επίτηδες για να το δοκιμάσω) και έλαβα το ακόλουθο αποτέλεσμα:

Στην περίπτωσή μου, το σενάριο χρειάστηκε λιγότερο από 2 δευτερόλεπτα για να τρέξει σε 40 διευθύνσεις URL. Το κέρδος απόδοσης είναι σημαντικό όταν ασχολείστε με ακόμη περισσότερες διευθύνσεις URL. Εάν ανοίξετε δέκα συνδέσεις ταυτόχρονα, το σενάριο μπορεί να εκτελεστεί δέκα φορές πιο γρήγορα.

Λίγα λόγια για άλλες χρήσιμες επιλογές cURL

Έλεγχος ταυτότητας HTTP

Εάν η διεύθυνση URL διαθέτει έλεγχο ταυτότητας HTTP, τότε μπορείτε εύκολα να χρησιμοποιήσετε το ακόλουθο σενάριο:

$url = "http://www.somesite.com/members/"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // καθορίστε το όνομα χρήστη και τον κωδικό πρόσβασης curl_setopt($ch, CURLOPT_USERPWD, "myusername:mypassword"); // εάν επιτρέπεται η ανακατεύθυνση curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // στη συνέχεια αποθηκεύστε τα δεδομένα μας στο cURL curl_setopt($ch, CURLOPT_UNRESTRICTED_AUTH, 1); $output = curl_exec($ch); curl_close($ch);

Μεταφόρτωση FTP

Η PHP διαθέτει επίσης μια βιβλιοθήκη για εργασία με FTP, αλλά τίποτα δεν σας εμποδίζει να χρησιμοποιήσετε τα εργαλεία cURL εδώ:

// άνοιγμα αρχείου $file = fopen("/path/to/file", "r"); // url θα πρέπει να περιέχει το ακόλουθο περιεχόμενο $url = "ftp://username: [email προστατευμένο]:21/path/to/new/file"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_UPLOAD, 1); curl_setopt($ch, CURLOPT_INFILE, $fp); curl_setopt($ch, CURLOPT_INFILESIZE, μέγεθος αρχείου("/διαδρομή/προς/αρχείο")); // προσδιορίστε το ASCII mod curl_setopt($ch, CURLOPT_FTPASCII, 1); $έξοδος = curl_ ($ch); curl_close($ch);

Χρήση διακομιστή μεσολάβησης

Μπορείτε να υποβάλετε το αίτημα URL μέσω διακομιστή μεσολάβησης:

$ch = curl_init(); curl_setopt($ch, CURLOPT_URL,"http://www.example.com"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // καθορίστε τη διεύθυνση curl_setopt($ch, CURLOPT_PROXY, "11.11.11.11:8080"); // εάν πρέπει να δώσετε όνομα χρήστη και κωδικό πρόσβασης curl_setopt($ch, CURLOPT_PROXYUSERPWD,"user:pass"); $output = curl_exec($ch); curl_close($ch);

Επανακλήσεις

Είναι επίσης δυνατό να καθοριστεί μια συνάρτηση που θα ενεργοποιείται ακόμη και πριν ολοκληρωθεί το αίτημα cURL. Για παράδειγμα, ενώ φορτώνεται το περιεχόμενο μιας απόκρισης, μπορείτε να αρχίσετε να χρησιμοποιείτε τα δεδομένα χωρίς να περιμένετε να φορτώσει πλήρως.

$ch = curl_init(); curl_setopt($ch, CURLOPT_URL,"http://net.tutsplus.com"); curl_setopt($ch, CURLOPT_WRITEFUNCTION,"progress_function"); curl_exec($ch); curl_close($ch); συνάρτηση progress_function($ch,$str) (echo $str; return strlen($str); )

Μια τέτοια συνάρτηση ΠΡΕΠΕΙ να επιστρέψει το μήκος της συμβολοσειράς, κάτι που είναι απαίτηση.

συμπέρασμα

Σήμερα γνωρίσαμε πώς μπορείτε να χρησιμοποιήσετε τη βιβλιοθήκη cURL για τους δικούς σας εγωιστικούς σκοπούς. Ελπίζω να σας άρεσε αυτό το άρθρο.

Ευχαριστώ! Να έχεις μια όμορφη μέρα!