Веб-сервисы и SoapClient

Общие вопросы по использованию фреймворка. Если не знаете как что-то сделать и это про Yii, вам сюда.
NetStranger
Сообщения: 107
Зарегистрирован: 2010.03.17, 12:54

Веб-сервисы и SoapClient

Сообщение NetStranger »

Проштудировал весь пример, все получается, но этого функционала мне мало
http://yiiframework.ru/doc/guide/ru/topics.webservice

Я хочу чтобы через API я мог авторизовываться и вносить данные в БД... Про первую часть я еще не задумывался, но вроде решение видел, а вот вносить в БД почему то не получается =(

пробую так:

Код: Выделить всё


         public function actions()
    {
        return array(
            'quote'=>array(
                'class'=>'CWebServiceAction',
            ),
        );
    }


      /**
     * @param array loaded news
     * @return string result of loading
     * @soap
     */
    public function LoadNews($news)
    {
                $post = new Test();

        $post->attributes = $news;
        if($post->save())
                return 'ok';
        else
            return 'nope';  
    }

public function actionGet()
        {
$client=new SoapClient('http://'.$_SERVER['SERVER_NAME'].'/api/quote');

echo $client->LoadNews(
    array(
        'title' => 'wefwefewf',
        'detail' => 'wefwefwqef',
    )
);
        }

 
Выдает ошибку Function ("LoadNews") is not a valid method for this service, интересно а где его прописывать?
А если я называю идентично встроенному методу , то он сохраняет какие то непонятные значения а не те что я передаю в массиве.. подскажите плиз.
Вот, что можно сделать с помощью Yii - Teutonick.ru
mitallast
Сообщения: 207
Зарегистрирован: 2010.02.21, 20:40
Откуда: Голицыно
Контактная информация:

Re: Веб-сервисы и SoapClient

Сообщение mitallast »

eAccelerator часом не используется ?
NetStranger
Сообщения: 107
Зарегистрирован: 2010.03.17, 12:54

Re: Веб-сервисы и SoapClient

Сообщение NetStranger »

нет, я вообще не в курсе что это
Вот, что можно сделать с помощью Yii - Teutonick.ru
NetStranger
Сообщения: 107
Зарегистрирован: 2010.03.17, 12:54

Re: Веб-сервисы и SoapClient

Сообщение NetStranger »

Блин кто нить подскажет все же? Или никто не пользовался этим ?
Как задавать эти хреновы методы? И почему вместо параметров он передает букву А в любом случае? что это вообще за хрень, откуда береться?
Вот, что можно сделать с помощью Yii - Teutonick.ru
mitallast
Сообщения: 207
Зарегистрирован: 2010.02.21, 20:40
Откуда: Голицыно
Контактная информация:

Re: Веб-сервисы и SoapClient

Сообщение mitallast »

простотрите phpinfo() и если там есть запись с eAccelerator, то проверить параметр enable.
Это кеширующая система , по сути что-то типа компилятора кеша для php.
В его ядре есть один баг, который удаляет комментарии - все, включая phpdoc которые должны быть доступны через Reflection - способ получать информацию о обьектах, классах и т.п информацию, в том числе и phpdoc комментарии методов и переменных класса.

Итак, у Вас включен eAccelerator с этим досадным багом. Тогда Ваш класс с прописаннымм phpdoc условными комментариями @soap просто вырежутся, и в итоге Yii ничего не увидит - а не увидит, решит что в классе нет ни одного доступной soap переменной или метода.

Потому в первую очередь нужно проверить именно eAccelerator.
NetStranger
Сообщения: 107
Зарегистрирован: 2010.03.17, 12:54

Re: Веб-сервисы и SoapClient

Сообщение NetStranger »

Вы правы отчасти, у мня нет eAccelerator, но была проблема с кешированием soap.wsdl_cache_enabled , я выставил значение 0 -и вроде как заработало, но это у меня на локальном, как быть если на удаленном хосте такие же грабли?
Вот, что можно сделать с помощью Yii - Teutonick.ru
mitallast
Сообщения: 207
Зарегистрирован: 2010.02.21, 20:40
Откуда: Голицыно
Контактная информация:

Re: Веб-сервисы и SoapClient

Сообщение mitallast »

Можно выставить соответствующие флаги в .htaccess
http://www.st-host.ru/help/index.php?id_article=25
Аватара пользователя
MaxOtto
Сообщения: 139
Зарегистрирован: 2010.01.30, 17:44

Re: Веб-сервисы и SoapClient

Сообщение MaxOtto »

На днях реализовал взаимодействие своего сервака и Excelя посредством SOAP. Может пригодится кому?

В контроллере у меня 2 функции, SOAPController.php пишу так:

Код: Выделить всё

class SOAPController extends CController
{
    public function actions()
    {
        return array(
            'quote'=>array(
                'class'=>'CWebServiceAction',
            ),
        );
    }

    /** 
     * @param string
     * @param string
     * @return string
     * @soap
     */
    public function getcodelist($filial_id, $secretword)
    {
    //предварительные объявления
        $out = 'Service is unavailable just now, try again later';
        if ($secretword <> 'какбысекретноеслово'){
            return $out;
        }
/*
   здесь идет основная логика
*/     
        return $out;
    }

    /**
     * @param string код объекта
     * @param string код объекта
     * @return string XML со свойствами объекта
     * @soap
     */
    public function getobjectrow($code, $secretword)
    {
//предварительные объявления
        $out = 'Service is unavailable just now, try again later';
        if ($secretword <> 'какбэсекретноеслово'){
            return $out;
        }
/*
здесь идет логика функции
*/
        return $out;
        }
 
Для контроля того, что получилось, использую 2 способа:
1 - чтобы узнать, что SOAP нормально функционирует в части объявлений, захожу по ссылке типа '....index.php?r=SOAP/quote'. В ответ получаю такой кусок текста

Код: Выделить всё

<definitions name="SOAPController" targetNamespace="urn:SOAPControllerwsdl">
−
<wsdl:message name="getcodelistRequest">
<wsdl:part name="filial_id" type="xsd:string"/>
<wsdl:part name="secretword" type="xsd:string"/>
</wsdl:message>
−
<wsdl:message name="getcodelistResponse">
<wsdl:part name="return" type="xsd:string"/>
</wsdl:message>
−
<wsdl:message name="getobjectrowRequest">
<wsdl:part name="code" type="xsd:string"/>
<wsdl:part name="secretword" type="xsd:string"/>
</wsdl:message>
−
<wsdl:message name="getobjectrowResponse">
<wsdl:part name="return" type="xsd:string"/>
</wsdl:message>
−
<wsdl:portType name="SOAPControllerPortType">
−
<wsdl:operation name="getcodelist">
<wsdl:documentation/>
<wsdl:input message="tns:getcodelistRequest"/>
<wsdl:output message="tns:getcodelistResponse"/>
</wsdl:operation>
−
<wsdl:operation name="getobjectrow">
<wsdl:documentation/>
<wsdl:input message="tns:getobjectrowRequest"/>
<wsdl:output message="tns:getobjectrowResponse"/>
</wsdl:operation>
</wsdl:portType>
−
<wsdl:binding name="SOAPControllerBinding" type="tns:SOAPControllerPortType">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
−
<wsdl:operation name="getcodelist">
<soap:operation soapAction="urn:SOAPControllerwsdl#getcodelist" style="rpc"/>
−
<wsdl:input>
<soap:body use="encoded" namespace="urn:SOAPControllerwsdl" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</wsdl:input>
−
<wsdl:output>
<soap:body use="encoded" namespace="urn:SOAPControllerwsdl" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</wsdl:output>
</wsdl:operation>
−
<wsdl:operation name="getobjectrow">
<soap:operation soapAction="urn:SOAPControllerwsdl#getobjectrow" style="rpc"/>
−
<wsdl:input>
<soap:body use="encoded" namespace="urn:SOAPControllerwsdl" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</wsdl:input>
−
<wsdl:output>
<soap:body use="encoded" namespace="urn:SOAPControllerwsdl" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
−
<wsdl:service name="SOAPControllerService">
−
<wsdl:port name="SOAPControllerPort" binding="tns:SOAPControllerBinding">
<soap:address location="http://localhost/psid/index.php?r=sOAP/quote&ws=1"/>
</wsdl:port>
</wsdl:service>
</definitions> 
2 - для контроля вызова непосредственно функций написал отдельный скрипт, вне фреймворка, checksoap.php

Код: Выделить всё

$client=new SoapClient('http://localhost/psid/index.php?r=SOAP/quote', array('cache_wsdl' => 0));
echo $client->getCodeList('0', 'какбысекретноеслово');
echo $client->getobjectrow('102501001', 'какбысекретноеслово'); 
В результате вижу то, что формируется в переменных $out, у меня там просто текст или XML.

Ну и отдельная песня, как это использовать на стороне Excel. Если интересно - продолжу.
mitallast
Сообщения: 207
Зарегистрирован: 2010.02.21, 20:40
Откуда: Голицыно
Контактная информация:

Re: Веб-сервисы и SoapClient

Сообщение mitallast »

с Excel не дружу, но заинтриговало. Пока не видел толковых статей по реальному использованию soap :(
Аватара пользователя
MaxOtto
Сообщения: 139
Зарегистрирован: 2010.01.30, 17:44

Re: Веб-сервисы и SoapClient

Сообщение MaxOtto »

Ок, завтра с работы отпишу про Ёксель, что да как.
Аватара пользователя
MaxOtto
Сообщения: 139
Зарегистрирован: 2010.01.30, 17:44

Re: Веб-сервисы и SoapClient

Сообщение MaxOtto »

Итак, предыстория такова: заказчик очень любит Excel и сильно просит, чтобы данные из БД можно было выводить в виде огромной портянки в 3000 строк и около сотни столбцов. Пробовал использовать PHPExcel. Он довольно удобен, но на больших файлах начинает тупить и не укладывается в типичный для многих хостингов временной интервал в 30-60 секунд. Выводить успевает строк 300, причем, основное время тратится не на выборку и укладку данных в ячейки, а именно на сборку окончательного файла для загрузки, то есть резервов для оптимизации моего кода не осталось, загвоздка - в ядре PHPExcel. В общем, решено было делать это через SOAP чтобы:
а) часть работы перенести на клиента (украшательства и излишества всякие нехорошие)
б) за счет использования небольших запросов обойти ограничение на время исполнения скрипта.

Идея:
Делать выборку в 2 шага. На первом шаге загружаем в шаблон список ключевых атрибутов большой выборки с учетом необходимых фильтраций и сортировок. На втором этапе для каждой строки Excel по ключевому атрибуту вытягивать с сервера содержимое одной строки. Я тащу по 2 значения на каждую ячейку - текст ячейки и её цвет.

Про серверную логику рассказал вчера. На стороне Excel необходимо провести следующие предварительные шаги:
1 - скачать и установить необходимые дополнительные компоненты
- SOAPToolkit 3.0 (http://www.microsoft.com/downloads/en/d ... laylang=en)
- MSXML 4.0, если ответ от сервера идет в виде XML и надо его разобрать (http://www.microsoft.com/downloads/en/d ... layLang=en)
2 - включить установленные компоненты, чтобы можно было использовать их в EXCEL VBA. В редакторе VBA идем в пункт меню TOOLS->References и ставим галочки на нужных компонентах (Microsoft Soap Type Library v3.0 и Microsoft XML, v6.0)
После этого можно начинать кодировать.
Я использовал следующий подход - на шаблоне имеется пустой лист с шапками и кнопка "обновить". По нажатию кнопки открывается форма, на которой задаются параметры запроса - фильтр по объектам, в моем случае и ввод пользовательского пароля (пока проверка пароля осуществляется на стороне Excelя с использованием "ЗАЩИТЫ ЛИСТА" и скрытия кода VBA). Есть кнопка начала процесса, ProgressBar, чтобы пользователь видел, сколько ему скучать. Ну и кнопка прерывания процесса, если уж совсем невмоготу ждать.

Текста VBA накручено много. Там и логика запароливания доступа для разных контрагентов, оживление ProgressBar и т.п хрень. Весь текст не выкладываю, так как к вопросу SOAP там относится совсем чуть. Принципиальные моменты такие:
1 - объявление переменной

Код: Выделить всё

Dim soapclient As SoapClient30
Суффикс "30" может меняться, в зависимости от того, какой тулкит скачан. У меня так для SOAPToolkit 3.0

2 - Создание экземпляра

Код: Выделить всё

Set soapclient = CreateObject("MSSOAP.SoapClient30")
 
3 - подготовка к использованию

Код: Выделить всё

soapclient.ClientProperty("ServerHTTPRequest") = True
Call soapclient.MSSoapInit("http://localhost/psid/index.php?r=SOAP/quote")
 
4 - вызов удаленной функции №1

Код: Выделить всё

XML = soapclient.getCodeList(Cells(1, 9), "какбысекретноеслово")
 
Здесь имеется ввиду, что значение параметра для передачи в удаленную функцию уже установлено в ячейке(1,9)

или №2

Код: Выделить всё

Line = soapclient.getobjectrow(code, "ещеболеесекретноеслово")
 
Вот собственно и всё. Остался единственный вопрос - надо ли (и как) уничтожать созданный экземпляр soapclient. Пока это не тяготит, но испытания насчет утечки памяти не проводил.

В качестве основы и учебного пособия использовал пример с сайта Центробанка - там они поясняют, как работать с их сервисами:
http://www.cbr.ru/scripts/Root.asp?Prtid=DWS
http://www.cbr.ru/scripts/MrrfSample.rar
mitallast
Сообщения: 207
Зарегистрирован: 2010.02.21, 20:40
Откуда: Голицыно
Контактная информация:

Re: Веб-сервисы и SoapClient

Сообщение mitallast »

Как минимум, круто :)

Представил себе админку сайта в виде excel, это бы впечатлило заказчиков :lol:
Аватара пользователя
MaxOtto
Сообщения: 139
Зарегистрирован: 2010.01.30, 17:44

Re: Веб-сервисы и SoapClient

Сообщение MaxOtto »

Спасибо на добром слове.
;)
На этом форуме я почерпнул много полезного и рад теперь поделиться своими находками. Надеюсь, кому-нить пригодится.
mitallast
Сообщения: 207
Зарегистрирован: 2010.02.21, 20:40
Откуда: Голицыно
Контактная информация:

Re: Веб-сервисы и SoapClient

Сообщение mitallast »

Soap в Yii вообще не очень освещен. Сегодня начал потихоньку писать простую(относительно) торговую площадку на soap, вопрос встал в авторизации клиента. Пример был найден на php.net без всяких, и применил его в yii. Надо заметить, документация для soap пока довольно скудная :?

Получился следующий минимальный код:

Код: Выделить всё

/**
 * контроллер soap
 */
class SoapController extends CController
{
    protected $authenticated = false;
    
    public function actions()
    {
        return array(
            'server'=>array(
                'class'=>'CWebServiceAction',
            ),
        );
    }
    
    /**
     * Авторизация клиента soap
     * @param string $username
     * @param string $password
     * @return boolean result of auth
     * @soap
     */
    public function auth($username, $password)
    {
        // классическая авторизация на yii
        $identity = new SoapIdentity($username, $password);
        if( $identity->authenticate() )
        {
            // авторизация сохраняется на один запрос и не для пользователя
            $this->authenticated = true;
        }
        return true;
    }
}

/**
 * Некий обьект, хранящий авторизационные данные
 */
class SoapAuth
{
    /** @var int password */
    public $password;
    /** @var int username */
    public $username;

    public function __construct($l, $p)
    {
        $this->password = $p;
        $this->username = $l;
    }
}

// подключаемя
$client = new SoapClient("http://localhost/commerce-soap/soap.php/soap/server");
// устанавливаем заголовок для авторизации
// магия состоит в том, что метод SoapController::auth() будет вызван именно перед действием вебсервиса.
$wsu = 'http://schemas.xmlsoap.org/ws/2002/07/utility';
$soapHeaders[] = new SoapHeader($wsu, 'auth', new SoapAuth("kuzp","pass"));
$client->__setSoapHeaders( $soapHeaders );

 
Аватара пользователя
MaxOtto
Сообщения: 139
Зарегистрирован: 2010.01.30, 17:44

Re: Веб-сервисы и SoapClient

Сообщение MaxOtto »

О как! Здорово!

Я бы сдуру нагородил-бы кучу своего авторизационного кода. Спасибо, в следующей версии переделаю на такую же авторизацию.
Аватара пользователя
BuCeFaL
Сообщения: 447
Зарегистрирован: 2010.03.17, 21:22
Откуда: Kiev
Контактная информация:

Re: Веб-сервисы и SoapClient

Сообщение BuCeFaL »

Кто то пробовал рабоать с SOAP когда сервер PHP клиент не PHP (Java, VC)?
Насколько я понял, работает оно в теории на практике не все так просто...
mitallast
Сообщения: 207
Зарегистрирован: 2010.02.21, 20:40
Откуда: Голицыно
Контактная информация:

Re: Веб-сервисы и SoapClient

Сообщение mitallast »

BuCeFaL писал(а):Кто то пробовал рабоать с SOAP когда сервер PHP клиент не PHP (Java, VC)?
Насколько я понял, работает оно в теории на практике не все так просто...
А какая разница чем xml разбирать ? Soap для php написан на языке C (или C++ ? ) так что особенных проблем быть не должно. Лишь бы wsdl был корректным.
Аватара пользователя
MaxOtto
Сообщения: 139
Зарегистрирован: 2010.01.30, 17:44

Re: Веб-сервисы и SoapClient

Сообщение MaxOtto »

Ну вот в моем примере в качестве клиента используется Excel с VBA. Если копнуть в MSDN, то там имеются примеры и на С и на С#.

Про ХМL: я решил, что мучиться с ним мне совсем не надо. В моей задаче структура ответа сервера жесткая, поэтому использую в качестве разделителя полей символ "|", по примеру форматов файлов Федерального Казначейства. Легко проебразовать в массив, накладные расходы по объему траффика минимальны.
mitallast
Сообщения: 207
Зарегистрирован: 2010.02.21, 20:40
Откуда: Голицыно
Контактная информация:

Re: Веб-сервисы и SoapClient

Сообщение mitallast »

Я имел в виду, что soap основан на xml , так что никакой привязки к платформе в принципе нету.
Аватара пользователя
MaxOtto
Сообщения: 139
Зарегистрирован: 2010.01.30, 17:44

Re: Веб-сервисы и SoapClient

Сообщение MaxOtto »

Ну да, тут согласен.
Ответить