php программист / php

Com_dotnet

COM и PHP.

Перевод статьи Вадим Крючков aka Long.
Оригинал находится по адресу http://www.zend.com/php5/articles/php5-dotnet.php

Введение

Нововведения в объектно-ориентированном (ОО) подходе PHP 5 не ограничиваются введением приватных (private), защищенных (protected) и публичных (public) переменных в ваших скриптах, позволяющие полноценно интегрировать поддержку внешних объектных моделей таких как COM, Java, .Net и Corba. Но это стало превосходной возможностью действительно оживить поддержку COM, которая, из-за ограничений объектной модели РНР 4, накладывала ограничения и на сами скрипты, и на использование СОМ-расширений. Для этого была полностью переписана поддержка СОМ и даже убрана обратная совместимость с наиболее неестественными аспектами СОМ-расширений РНР 4.

Более не поддерживается

Следующие функции и возможности более не поддерживаются в работе с COM в PHP 5, так как они, вообще говоря, плохо согласуются с самой идеей COM, и больше сбивают с толку, если вы посмотрите их описание в документации.

com_addref(), com_release() – скрипт может больше не заботится о счетчике ссылок

com_get(), com_set(), com_invoke(),com_propget(), com_propset(), com_propput() – логичнее использовать обычный ОО синтаксис РНР для получения или установки свойств или вызова методов объекта.

com_isenum() и $com->Next() – теперь используйте вместо этого синтаксис foreach(), описанный ниже.

com_load() – вместо этого используйте оператор new и встроенный класс СОМ.

Итак, весь этот хлам будет уничтожен. А теперь посмотрим, какие "вкусности" будут добавлены.

Iterators 1

Если вы когда-либо имели дело с VBscript, например, при написании ASP сайтов или административных vbs-скриптов, вы непременно видели подобный код:

<% 
set domainObject = GetObject("WinNT://Domain")
for each obj in domainObject
Response.write obj.Name & "<br>"
next
%>

В СОМ для PHP 4, эквивалентный код выглядит так:


<?php 

$domainObject 
= new COM("WinNT://Domain"); 

while (
$obj $domainObject->Next()) { 

  echo 
$obj->Name "&lt;br&gt;"



?>



Если вы подробно изучали VB/COM, взглянув на этот пример, вас должно удивить, что именно Next() производит перебор, так как это не реально существующий метод класса, и вы ни за что не найдете его в других языках, поддерживающих СОМ. В РНР 5 такой синтаксис был упразднен за счет более подходящего для этих целей оператора foreach():


<?php 

$domainObject 
= new COM("WinNT://Domain"); 

foreach (
$domainObject as $obj) { 

  echo 
$obj->Name "<br>"



?>



Обработка исключений

В РНР 4 не было нормальных возможностей для реализации обработчика ошибок, срабатывающего в пределах СОМ-кода при возникновении ошибки. РНР позволял устанавливать E_WARNING, для того чтобы узнать, что случилась ошибка, но вы не имели возможности узнать точно - в какой момент и при каких условиях случилась ошибка, чтобы программно ее обработать.

В PHP 5 вводится новая конструкция, позволяющая обработать исключительные ситуации (try, catch() и throw()), которая позволяет обрабатывать исключения, используя встроенный в РНР класс com_exception. Если Вы хотите отловить ошибки в ваших скриптах, вы могли бы написать примерно такой код:


<?php 

$com 
= new COM("..."); 

try { 

  
$com->call_a_method(); 



catch (
com_exception $e) { 

  print 
$e "\n"



?>



Внутри блока catch вы можете обрабатывать ошибку наиболее подходящим вашей программе способом. Класс com_exception является расширением базового класса обработки исключений exception, предоставляемого РНР, и включает все его методы. Код ошибки доступен через метод getCode() класса, делая легким обработку специфических ошибок.

Тип Variant

Одной из не очень хорошо задокументированных особенностей СОМ в РНР 4 является поддержка типа данных VARIANT. Если вы не знакомы с этим типом данных, то можете представлять его, как некий эквивалент переменной РНР, которая может содержать данные различных типов (целые, переменные с плавающей точкой, строковые или объекты). Тип variant, использующийся в СОМ, более разнообразен, чем просто РНР переменные, и не всегда может быть приведен к "родным" типам РНР. Поддержка типа variant в РНР 4 такова, что зависит от направления преобразования между СОМ и РНР, и в результате мы имели кошмарный код обработки преобразований типов данных. К тому же, это было чревато множеством ошибок и не позволяло обрабатывать все возможные случаи преобразования. Не исключена была даже возможность, что при преобразовании вы могли потерять данные или их точность.

В PHP 5 работа с variant сильно упрощена. Теперь преобразование типов исходит из предпосылки, что нужно преобразовывать переменную типа variant к "родному" типу PHP, только когда есть возможность прямого, один-к-одному преобразования. Во всех остальных случаях, мы представляем тип variant как перегруженный объект, и откладываем выбор конечного типа до момента пока он не будет использоваться в выражении. Как следствие, мы имеем намного понятный и чистый код и, если вы работаете с массивами, элементы которых имеют тип variant, намного быстрее работающие скрипты, поскольку мы больше не должны копировать содержимое исходного массива в массив PHP - новая модель OO в PHP 5 позволяет нам получать доступ к объекту variant, как если бы это был обычный массив.

Другой приятный момент, ставший возможным благодаря новой модели OO - интеллектуальная интерпретация содержимого объекта variant, используя обработчик приведения типов. Как я говорил выше, мы откладываем выбор конечного типа, пока объект не будет использован в выражении. В момент подстановки, Zend Engine рассматривает в каком контексте используется объект (числовой, строковый и т.д.) и преобразует объект к соответствующему типу. Такой подход позволяет точно конвертировать переменную.

Если этого не достаточно, существует большое количество различных API-функций COM, которые позволяют вам суммировать, вычитать, умножать и производить иные действия с типом variant согласно таким же правилам, которые используются в VB. С одной стороны, такая возможность для базовых типов (целые числа и строки) не кажется полезной , но оказывается крайне это полезной и необходимой для "экзотических" типов (даты, валюты и других).

Передача параметров по ссылке (ByRef)

Обычной ситуацией при работе с СОМ объектами является передача параметров по ссылке. В PHP 4, единственной возможностью передать тип variant по ссылке, было вручную создать экземпляр variant и передать его как ссылку. Модель OO в PHP 5 позволяет РНР движку самостоятельно получать от COM-объекта информацию о методе, который будет вызван, чтобы определить, какие параметры необходимо передать по ссылке. Это позволяет вам вызывать СОМ-методы, не заботясь о методе передачи переменных - нужный метод будет установлен автоматически.

Управление событиями

Строго говоря, это не является нововведением для PHP 5 (и было добавлено еще это в PHP 4.3), но об этом стоит упомянуть здесь, так как такая возможность не была хорошо задокументирована. Весьма часто вы должны связать с СОМ объектом определенное событие. В VB, для этих целей используется оператор WithEvents при определении переменной, и Visual Basic будет вызывать метод автоматически. В РНР есть небольшие отличия, но при этом подход более последователен.

Чтобы обрабатывать события от COM объекта-источник, вы должны создать объект, который будет получать эти события. Для этого вы просто определяете свой класс-приемник сообщений, создаете экземпляр этого класса, а затем связываете события с ним:


<?php 

// класс-приемник сообщений

class IESink 

   var 
$terminated false

   function 
OnQuit() { $this->terminated true; } 

}

// создаем экземпляр класса IESink

$sink = new IESink

// создаем экземпляр СОМ, связанный с IE

$ie = new COM("InternetExplorer.Application"); 

// связываем события СОМ-объекта с нашим обработчиком

com_event_sink($ie$sink"DWebBrowserEvents2"); 

$ie->Visible true// отображаем IE

$ie->Navigate("http://www.php.net/"); // загружаем страницу http://www.php.net

// ожидаем закрытия браузера

while (!$sink->terminated) { 

   
com_message_pump(4000); 



?> 


Этот скрипт запускает Interne Explorer и загружает домашную страницу PHP (http://www.php.net/) и будет ожидать закрытия браузера для продолжения. Нужно отметить, что com_event_sink () функция отвечает за установку пересылки событий от $ie к $sink, и что используется интерфейс "DWebBrowserEvents2". Название интерфейса должно точно соответствовать названию так называемого внешнего диспетчерского интерфейса (интерфейс, который осуществляет доступ к сервисам COM-объектов) для вашего COM объекта. Вы можете узнать название и также сгенерировать шаблон класса-приемника, используя функцию com_print_typeinfo().

Поддержка .Net

В РНР 5 встроена поддержка .Net. Если быть более точным, поддерживается экземпляр объектов, определенных в .Net-сборках через взаимодействия с COM-оберткой. Т.е. можно считать, что PHP "видит" объекты .Net так, как если бы они были объектами COM, хотя экземпляры объектов немного отличаются:


<?php 

  $stack 
= new DOTNET("mscorlib""System.Collections.Stack"); 



  
$stack->Push(".Net"); 

  
$stack->Push("Hello "); 



  echo 
$stack->Pop() . $stack->Pop(); 

?> 


Таким образом, РНР 5 предоставляет Вам удобный доступ к очень обширной библиотеке .Net классов (которая насчитывает несколько тысяч различных классов!). Разумеется, чтобы использовать эти возможности вы должны установить .Net RunTime на ваш сервер.

Заключение

Хотя каждая возможность, которую я упомянул выше, по отдельности не столь значима, общий эффект от нового подхода можно ощутить, если вы когда-либо писали скрипты используя возможности СОМ. Вы обнаружите, что скрипт стал не только много короче, легко читаемым и понимаемым, но стал и быстрее выполняться.

Вы можете попробовать все эти возможности прямо сейчас, загрузив снапшот PHP 5 (http://snaps.php.net). В настоящее время PHP 5 находится в стадии стабилизации кода, готовится первый стабильный релиз. Текущая версия (на момент перевода Release Candidate 2) уже довольно стабильна, так что вы можете приступать непосредственно к полевым испытаниям. Если Вы сталкиваетесь с проблемами, пожалуйста, сообщите о них по адресу http:// bugs.php.net.

Об авторе

Wez Furlong - разработчик ядра PHP и "главный" по PECL (The PHP Extension Community Library), содействовавший разработкам расширений, таких как SQLite, COM/.Net, ActivePHP, mailparse, Streams API и другим.


1 iterator - управляющая структура, определяющая порядок выполнения некоторых повторяющихся действий, устройство или программа организации циклов.




Немного Рекламы...

услуги телемаркетинга ; купить мобильный телефон nokia ,