Информация
Настройка
Новости
Контакты
Новинка
Распродажа
Оплата
Доставка
Загрузки
  • Прошивки
    • WinBox
    • RouterOS
    • Мобильные приложения MikroTik
    • Архив
  • Changelogs
  • RouterOS
  • Мобильные приложения MikroTik
  • Архив
Форум
Услуги
  • Внедрение
  • Настройка
  • Поддержка
  • Ремонт
    info@mikrotik.moscow
    +7 495 320-55-52
    Заказать звонок
    Mikrotik.moscow
    Каталог
    • Акции
      Акции
    • Маршрутизаторы
      Маршрутизаторы
    • Коммутаторы
      Коммутаторы
    • Радиомосты и уличные точки доступа
      Радиомосты и уличные точки доступа
    • Wi-Fi для дома и офиса
      Wi-Fi для дома и офиса
    • LTE/5G
      LTE/5G
    • Powerline адаптеры
      Powerline адаптеры
    • IoT устройства
      IoT устройства
    • Оборудование 60 ГГц
      Оборудование 60 ГГц
    • Материнские платы RouterBOARD
      Материнские платы RouterBOARD
    • Корпуса
      Корпуса
    • Интерфейсы
      Интерфейсы
    • SFP/QSFP трансиверы
      SFP/QSFP трансиверы
    • Аксессуары
      Аксессуары
    • Антенны
      Антенны
    • Архив
      Архив
    Войти
    0 Сравнение
    0 Избранное
    0 Корзина
    Скачать WinBox Скачать Прошивки Форум > RouterOS Форум > SwOS Форум > Железо
    Mikrotik.moscow
    Каталог
    Войти
    0 Сравнение
    0 Избранное
    0 Корзина
    Mikrotik.moscow
    Телефоны
    +7 495 320-55-52
    Заказать звонок
    0
    0
    0
    Mikrotik.moscow
    • +7 495 320-55-52
      • Назад
      • Телефоны
      • +7 495 320-55-52
      • Заказать звонок
    • info@mikrotik.moscow
    • г. Москва, ул. Бакунинская, 84
    • Пн-Пт: 09-00 до 18-00
      Сб-Вс: выходной


    • Кабинет
    • 0 Сравнение
    • 0 Избранное
    • 0 Корзина
    Главная
    Форум
    RouterOS
    API – проблема с получением списка пулов.

    API – проблема с получением списка пулов.

    Форумы: RouterOS, Аппаратное обеспечение, SwOS, Обратная связь, Объявления, Сторонние инструменты
    Поиск  Пользователи  Правила  Войти
    Страницы: 1
    RSS
    API – проблема с получением списка пулов., RouterOS
     
    LeoCombes
    Guest
    #1
    0
    06.01.2014 22:49:00
    Привет! Пытаюсь получить IP-пулы через API. Когда пытаюсь из терминала, получаю: [admin@mktk] > ip pool print
    # NAME                                                                                                                     RANGES                        
    0 pool_red_slave                                                                                                           192.168.3.100-192.168.3.200
    1 pool_red_slave2                                                                                                          192.168.4.100-192.168.4.200
    2 pool_privadas                                                                                                            172.16.1.2-172.16.1.254        
    3 pool_prueba                                                                                                              10.10.10.100-10.10.10.200      
    4 pool_DVR                                                                                                                 192.168.2.100-192.168.2.200

    Когда пытаюсь с PHP командой ‘/ip/pool/print’ через PEAR2_Net_RouterOS, получаю только первый результат: .id “*1” name “pool_red_slave” next-pool “pool_red_slave2” ranges “192.168.3.100-192.168.3.200”

    Routerboard - RB1100Hx2 v5.20

    У кого-нибудь такое же поведение?
     
     
     
    boen_robot
    Guest
    #2
    0
    07.01.2014 11:10:00
    Как выглядит твой PHP-код? Подозреваю, что ты используешь возможность напрямую читать первый ответ, вместо того чтобы перебирать все ответы.
     
     
     
    LeoCombes
    Guest
    #3
    0
    07.01.2014 12:57:00
    Спасибо, Boen_robot! // $vars содержат все данные для входа
    $response = test($vars, '/ip/pool/print');

    function test($nas_access_data, $commands){
    $response = array("error" => 0);
    $login = mktk_login($nas_access_data);

    if($login['error'] == 0){
    $Request = new \PEAR2\Net\RouterOS\Request($commands);
    $result = $login['client']->sendSync($Request);
    $response[$commands] = $result->getAllArguments();
    }
    else $response = $login;
    return $response;
    }
     
     
     
    boen_robot
    Guest
    #4
    0
    07.01.2014 13:10:00
    Ну вот, как я и думал. $result содержит все ответы, но $result->getAllArguments(); показывает все аргументы первого ответа, а не все аргументы всех ответов. Чтобы получить все аргументы, нужно перебрать ответы или обратиться к коллекции. Например: $result = $login['client']->sendSync($Request);
         $response[$commands] = array();
         foreach ($result as $item) {  
           $response[$commands][] = $item->getAllArguments();
         }  тогда $response[‘/ip/pool/print’] будет числовым массивом, где каждый элемент – это массив всех аргументов для конкретного ответа. Другими словами, $response[‘/ip/pool/print’][0] будет содержать аргументы для первого пула, $response[‘/ip/pool/print’][1] – для второго пула и так далее.
     
     
     
    LeoCombes
    Guest
    #5
    0
    07.01.2014 13:48:00
    Спасибо, Boen_robot! Мой код работает отлично без изменений с getAllArguments() в случаях, когда возвращаются только аргументы: /system/resource/print /ppp/active/print count-only /ip/pool/used/print count-only /interface/monitor-traffic interface=ether1 once.

    Но для случаев команд, которые возвращают коллекцию (например, ‘/ip/pool/print’), мне нужно перебирать ответ. Тогда как я могу заранее узнать, какой тип ответа я получу? Если бы я знал, я бы сделал так (псевдокод):

    $result = $login['client']->sendSync($Request);
    if($result is collection){
    // если это коллекция, нужно перебирать
         foreach ($result as $item) {  
               $response[$commands][] = $item->getAllArguments();
         }
    }
    else{
    // если не коллекция...
    $response[$command] = $result->getAllArguments();
    }

    Как узнать, является ли ответ коллекцией или нет? Возможно ли это?
     
     
     
    boen_robot
    Guest
    #6
    0
    07.01.2014 14:01:00
    Все ответы – это сборник как минимум из одного ответа, поэтому можно безоговорочно перебирать всё. Все примеры, которые ты привёл, содержат ровно один ответ в этом сборнике. Один из них содержит всё необходимое, именно поэтому вызов getAllArguments() работает как и ожидается. Главная причина, по которой итерация не требуется, заключается именно в случаях, подобных этим. Ты можешь проверить количество, вызвав функцию count() над сборником, например: if(count($result) > 1) {
    //Ты ОБЯЗАН перебирать
    } else {
    //Перебирать не обязательно, но ты МОЖЕШЬ, если хочешь
    }
     
     
     
    LeoCombes
    Guest
    #7
    0
    07.01.2014 15:12:00
    Во-первых, спасибо за ваше время и вклад в разработку пакета PEAR API, это очень полезно для меня и других людей. Хорошая идея, но эта логика не всегда работает. Некоторые команды `count()` возвращают 1 или 2, даже если есть только 1 результат, например: `/system/resource/print`
    responseTypes = array(
    [0] =>'!re'
    [1] =>'!done'
    )
    count = 2

    `/ppp/active/print count-only`
    responseTypes = array(
    [0] =>'!done'
    )
    count = 1

    `/ip/pool/used/print count-only`
    responseTypes = array(
    [0] =>'!done'
    )
    count = 1

    `/interface/monitor-traffic interface wan_ether1 once`
    responseTypes = array(
    [0] =>'!re'
    [1] =>'!done'
    )
    count = 2

    `/ip/pool/print`
    responseTypes = array(
    [0] =>'!re'
    [1] =>'!re'
    [2] =>'!re'
    [3] =>'!re'
    [4] =>'!re'
    [5] =>'!done'
    )
    count = 6 Почему некоторые команды возвращают !re+!done, а другие только !done?
     
     
     
    LeoCombes
    Guest
    #8
    0
    07.01.2014 16:14:00
    Итоговое решение, код предлагаю тебе с небольшой модификацией. $result_count = count($result);
    if($result_count == 1){
    $response[$command] = $result->getAllArguments();
    }
    else if($result_count > 1){
    foreach ($result as $item) {
    if($item->getType() == "!re"){
    $response[$command][] = $item->getAllArguments();
    }
    }
    } В общем, мне всё ещё интересно, почему некоторые команды возвращают !re+!done, а другие только !done. Спасибо!
     
     
     
    boen_robot
    Guest
    #9
    0
    07.01.2014 20:58:00
    Во-первых, спасибо за потраченное время здесь и над разработкой пакета PEAR API, это очень полезно для меня и для других людей. Признателен. Спасибо.

    В любом случае, мне все еще интересно, почему некоторые команды возвращают !re+!done, а другие только !done. Это точно решение MikroTik (а не мое)... Я могу только предполагать их мотивацию. Обычно это связано с тем, что команда МОЖЕТ вернуть ноль или более одного элемента, но это очевидно не так с "/system/resource/print". Я предполагаю, что это для обратной совместимости: в случае "print" вы явно указываете режим работы, который всегда возвращает единственное значение (поэтому они могут позволить себе перейти от нескольких ответов !re к одному !done), но с ресурсами, возможно, они решат позже изменить то, как это работает, так, чтобы были множественные ответы данных (например, один для каждой "группы", как в Winbox), и некоторая часть того, что мы видим сейчас, останется в первом ответе (например, секция с версией), а ответы, которые мы получаем сейчас, будут совместимы с ответами тогда.

    Кстати, коллекция не может быть меньше 1, так что вы можете упростить свой код. Кроме того, если вы собираетесь фильтровать по типу, вы можете использовать метод getAllOfType() коллекции, например:

    ```
    if(count($result) == 1){
       $response[$command] = $result->getAllArguments();
    }
    else {
       $response[$command] = array();
       foreach ($result->getAllOfType('!re') as $item) {
           $response[$command][] = $item->getAllArguments();
       }
    }
    ```

    Обратите внимание: как в вашем коде, так и в этом, в случае ошибки будет возвращен пустой массив, что может быть не то, что вам нужно. Если вам нужно проверять наличие ошибок, проверьте $result->getAllOfType('!trap').
     
     
     
    LeoCombes
    Guest
    #10
    0
    08.01.2014 15:43:00
    Спасибо за разъяснения!
     
     
     
    Страницы: 1
    Читают тему
    +7 495 320-55-52
    info@mikrotik.moscow
    Электрозаводская, Бауманская
    Москва, ул. Бакунинская, 84с21
    Конфиденциальность Оферта
    © 2025 «Mikrotik.Moscow»
    Главная Каталог 0 Корзина 0 Избранные Кабинет 0 Сравнение Акции Контакты Услуги Бренды Отзывы Компания Лицензии Документы Реквизиты Поиск Блог Обзоры