Один компонент SCA может вызвать сервис, предоставляемый другим компонентом SCA. Сервис, предоставляемый компонентом, состоит из всех его публичных методов. В настоящее время SCA предоставляет два способа для одного компонента вызвать другой: либо локально (т.е. в рамках одного и того же процесс PHP, и в том же стеке вызовов), либо удаленно, если вызываемый компонент предоставляет привязку веб-сервиса.
Чтобы один компонент мог вызвать другого, вызывающему компоненту нужен прокси для вызываемого компонента. Этот прокси обычно предоставляется в качестве переменной экземпляра в вызывающем компоненте, хотя прокси также можно получить с помощью вызова SCA::getService(). Когда компонент сконструирован, прокси создаются для любой переменной экземпляра, которая относится к другому компоненту, и эти прокси "вводятся" в переменные экземпляра. Прокси используются всегда, независимо от того, является ли компонент локальным или удаленным, что обеспечивает идентичное поведение локальных и удаленных вызовов (например, локальные вызовы всегда позволяют передавать данные по-значению). Прокси знают, как найти необходимый компонент и передать сделанные им вызовы.
Переменные экземпляра, предназначенные для хранения прокси для сервисов, обозначаются двумя аннотациями в стиле PHPDocumentor, @reference и @binding. Обе аннотации размещаются в разделе документации для переменной экземпляра класса, как показано в приведенном ниже коде.
Аннотация @reference перед переменной указывает, что она должна быть инициализирована прокси-компонентом.
Аннотация @binding имеет две формы: @binding.php и @binding.soap, и указывает, что прокси предназначен либо для локального компонента, либо для веб-сервиса соответственно. Для обоих аннотаций @binding.php и @binding.soap задается целевой URI.
В настоящий момент, из-за метода определения зависимостей на основе аннотаций, единственным способом изменения целевой ссылки является изменение аннотации внутри компонента.
В нашем примере ConvertedStockQuote, переменная экземпляра $exchange_rate будет инициализирована как прокси к локальному компоненту ExchangeRate каждый раз, когда будет создаваться экземпляр класса ConvertedStockQuote.
Пример #1 Получение прокси для локальных классов
<?php
/**
* Сервис предоставления курсов обмена.
*
* @reference
* @binding.php ../ExchangeRate/ExchangeRate.php
*/
public $exchange_rate;
?>
URI в @binding.php указывает местоположение скрипта, содержащего реализацию компонента. Компонент будет называться локально. Предоставляемый сервис является набором публичных методов компонента. URI должен быть простым путем, абсолютным или относительным. Компонент будет загружен директивой include после проверки функцией class_exists(), не загружен ли он уже. Если URI является относительным путем, то он разрешается относительно компонента, содержащего аннотацию. Обратите внимание, что это отличается от обычного поведения PHP, когда скрипты ищутся по пути include_path. Это позволяет обеспечить некоторую независимости от местоположения для кросс-компонентных ссылок.
Для сервиса ExchangeRate, который мы используем удаленно, меняется только строка @binding. Вместо указания местоположения класса PHP, мы указываем местоположение WSDL, описывающей веб-сервис:
Пример #2 Получение прокси для веб-сервиса
<?php
/**
* Сервис получения биржевых котировок.
*
* @reference
* @binding.soap ../StockQuote/StockQuote.wsdl
*/
public $stock_quote;
?>
Компонент StockQuote будет вызываться как веб-сервис. В этом случае URI для WSDL может быть простым именем пути или может содержать обертку PHP и начинаться, например, с file:// или http://. В случае, если это простой путь, он может быть абсолютным или относительным, и если он будет относительным, то он будет разрешаться относительно компонента с аннотацией. Обратите внимание, что как и для @binding.php, поведение будет отличается от обычного поведения PHP, когда скрипты ищутся по пути include_path. Это позволяет обеспечить некоторую независимости от местоположения для кросс-компонентных ссылок.