callback функция для curl

Тема в разделе "PHP", создана пользователем kud, 2 июн 2009.

Статус темы:
Закрыта.
Модераторы: latteo
  1. kud

    kud Постоялец

    Регистр.:
    18 фев 2009
    Сообщения:
    89
    Симпатии:
    11
    Можно ли как-то сделать callback для curl в который можно передать какой-то параметр.
    Можно как-то реализовать нечто подобное?:
    PHP:
    <?php
    //
    foreach ($array as $key => $value) {
     list(
    $url,$referer,$alias) = $value;
     
    getContent($url,$referer,$alias);
    }
    //
    function getContent($url,$referer,$alias) {
     
    $ch curl_init($url);
     
    // установка опций
     
    curl_setopt($chCURLOPT_WRITEFUNCTION‘curlCallback’);
     
    $content curl_exec($ch);
    }
    function 
    curlCallback($ch$content$alias) {
     switch(
    $alias) {
     case 
    '1' :
      
    // код
     
    break;
     case 
    '2' :
      
    // код
     
    break;
    }
    }
    ?>

    То есть, нужно что-б в цикле foreach работал быстро, не дожидаясь когда getContent вернет результат, ну вобщем как правильно реализовать callback ?
     
  2. PHP_Master

    PHP_Master

    Регистр.:
    3 фев 2008
    Сообщения:
    2.647
    Симпатии:
    590
    Смотри в сторону multi_curl.
     
  3. kud

    kud Постоялец

    Регистр.:
    18 фев 2009
    Сообщения:
    89
    Симпатии:
    11
    Посмотрел :)
    Если честно, с документацией как-то скудненько получается ... Нарыл пару кастом классов и все такое, но все же меня интересует как реализовать callback и, если ты, например, юзал эту штуку то интерессно узнать во сколько потоков будет оптимально работать? И если не впадляк, приведи короткий пример каллбека на примере предыдущего поста.. Буду очень благодарен.
    Извини если что не так )
     
  4. PHP_Master

    PHP_Master

    Регистр.:
    3 фев 2008
    Сообщения:
    2.647
    Симпатии:
    590
    Пример с php.net
    PHP:
    <?php
    /**
    * Multiple Curl Handlers
    * @author Jorge Hebrard ( jorge.hebrard@gmail.com )
    **/
    class curlNode{
        static private 
    $listenerList;
        private 
    $callback;
        public function 
    __construct($url){
            
    $new =& self::$listenerList[];
            
    $new['url'] = $url;
            
    $this->callback =& $new;
        }
        
    /**
        * Callbacks needs 3 parameters: $url, $html (data of the url), and $lag (execution time)
        **/
        
    public function addListener($callback){
            
    $this->callback['callback'] = $callback;
        }
        
    /**
        * curl_setopt() wrapper. Enjoy!
        **/
        
    public function setOpt($key,$value){
            
    $this->callback['opt'][$key] = $value;
        }
        
    /**
        * Request all the created curlNode objects, and invoke associated callbacks.
        **/
        
    static public function request(){
       
            
    //create the multiple cURL handle
            
    $mh curl_multi_init();
           
            
    $running=null;
           
            
    # Setup all curl handles
            # Loop through each created curlNode object.
            
    foreach(self::$listenerList as &$listener){
                
    $url $listener['url'];
                
    $current =& $ch[];
               
                
    # Init curl and set default options.
                # This can be improved by creating
                
    $current curl_init();

                
    curl_setopt($currentCURLOPT_URL$url);
                
    # Since we don't want to display multiple pages in a single php file, do we?
                
    curl_setopt($currentCURLOPT_HEADER0);
                
    curl_setopt($currentCURLOPT_RETURNTRANSFER1);
               
                
    # Set defined options, set through curlNode->setOpt();
                
    if (isset($listener['opt'])){
                    foreach(
    $listener['opt'] as $key => $value){
                        
    curl_setopt($current$key$value);
                    }
                }
               
                
    curl_multi_add_handle($mh,$current);
               
                
    $listener['handle'] = $current;
                
    $listener['start'] = microtime(1);
            } unset(
    $listener);

            
    # Main loop execution
            
    do {
                
    # Exec until there's no more data in this iteration.
                # This function has a bug, it
                
    while(($execrun curl_multi_exec($mh$running)) == CURLM_CALL_MULTI_PERFORM);
                if(
    $execrun != CURLM_OK) break; # This should never happen. Optional line.
               
                # Get information about the handle that just finished the work.
                
    while($done curl_multi_info_read($mh)) {
                    
    # Call the associated listener
                    
    foreach(self::$listenerList as $listener){
                        
    # Strict compare handles.
                        
    if ($listener['handle'] === $done['handle']) {
                            
    # Get content
                            
    $html curl_multi_getcontent($done['handle']);
                            
    # Call the callback.
                            
    call_user_func($listener['callback'],
                            
    $listener['url'],
                            
    $html,(microtime(1)-$listener['start']));
                            
    # Remove unnecesary handle (optional, script works without it).
                            
    curl_multi_remove_handle($mh$done['handle']);
                        }
                    }
                   
                }
                
    # Required, or else we would end up with a endless loop.
                # Without it, even when the connections are over, this script keeps running.
                
    if (!$running) break;
               
                
    # I don't know what these lines do, but they are required for the script to work.
                
    while (($res curl_multi_select($mh)) === 0);
                if (
    $res === false) break; # Select error, should never happen.
            
    } while (true);

            
    # Finish out our script ;)
            
    curl_multi_close($mh);
       
        }
    }
    $curlGoogle = new curlNode('http://www.google.com/');
    $curlGoogle->setOpt(CURLOPT_HEADER0);
    $curlGoogle->addListener('callbackGoogle');

    $curlMySpace = new curlNode('http://www.myspace.com/');
    $curlMySpace->addListener('callbackMySpace');

    curlNode::request();
    ?>
    Если хочется нормальной работы в несколько потоков, забудь про PHP.
     
  5. kud

    kud Постоялец

    Регистр.:
    18 фев 2009
    Сообщения:
    89
    Симпатии:
    11
    Да вот я тоже подозреваю о том что php как-то с обработкой событий особо не очень ... Что посоветуешь подучить ? Perl ?

    PS Может даже скинь автора и книгу которую стоит прочитать ?!
     
  6. PHP_Master

    PHP_Master

    Регистр.:
    3 фев 2008
    Сообщения:
    2.647
    Симпатии:
    590
    Смысл этой фразы остался для меня недоступным.

    Если ты мазохист, то сгодится.
    Я предпочитаю Python.
     
  7. upandhigh

    upandhigh

    Регистр.:
    11 фев 2009
    Сообщения:
    235
    Симпатии:
    89
    мультикурл прекрасно пашет в ПХП, мультипоточность юзается курловой либы а не пыхи поэтому проблем никаких нету. в мультикурл принцип очень прост - ты создаешь массив КУРЛОВЫХ хендлов даешь им задания и запускаешь потом бегаешь по кругу и смотришь какой из них готов, забираешь его обрабатываешь как тебе нужно - и вместо него добавляешь новый хендл (точнее меняешь параметры текущего) и он идет выполняться, поэтому разницы особой в реализации нету - и сваливать на другой язык из за этого смысла тоже нету. я лично юзал в ПХП и в Питоне в промышленных масштабах так сказать - никаких проблем не выявил. единственно в питоне нада вырубать сигналы иначе курловые потоки раньше времени вылетает и могут возвращать пустые данные, после пыхи это было непривычно ) там все работало без этого.
     
  8. PHP_Master

    PHP_Master

    Регистр.:
    3 фев 2008
    Сообщения:
    2.647
    Симпатии:
    590
    Многопоточность (не только для загрузки урлов) в Python реализована намного лучше.
    В PHP - пока-что находится в зачаточном состоянии.
     
  9. kud

    kud Постоялец

    Регистр.:
    18 фев 2009
    Сообщения:
    89
    Симпатии:
    11
    Ну, х.з. я вобще в программировании не спец. Просто например в Actionscript (Flash) есть такое понятие как обработка событий .. Очень удобная штука ) Ну, не буду о примерах, но думаю что ты понял о чем я ...

    Ну я то не то что-бы мазохист, просто считал что питон с perl имеют что-то общее?! Вернее питон как-то от перла унаследовался или что-то такое ...
    Или там вобще синтаксис не тот ?
     
  10. upandhigh

    upandhigh

    Регистр.:
    11 фев 2009
    Сообщения:
    235
    Симпатии:
    89
    если ты глянешь код курловый либы у пыхи то ты увидишь там просто врапер к ЛИБКУРЛУ (интерфейс), поэтому в случае с КУРЛОМ мультипоточность ПЫХИ не имеет никакого отношения.
     
Статус темы:
Закрыта.