如何通过 PHP 使用通知中心How to use Notification Hubs from PHP

如 MSDN 主题通知中心 REST API 中所述,可以使用通知中心 REST 接口从 Java/PHP/Ruby 后端访问所有通知中心功能。You can access all Notification Hubs features from a Java/PHP/Ruby backend using the Notification Hub REST interface as described in the MSDN topic Notification Hubs REST APIs.

本主题中,我们将向你介绍如何:In this topic we show how to:

  • 以 PHP 构建 REST 客户端以获取通知中心功能;Build a REST client for Notification Hubs features in PHP;
  • 请按照选定移动平台的入门教程操作,用 PHP 实现后端部分。Follow the Get started tutorial for your mobile platform of choice, implementing the backend portion in PHP.

客户端接口Client interface

主要的客户端接口可提供 .NET 通知中心 SDK 中提供的相同方法,这允许直接翻译当前此站点上提供的所有教程和示例,这些内容均来自 Internet 上的社区。The main client interface can provide the same methods that are available in the .NET Notification Hubs SDK, which allows you to directly translate all the tutorials and samples currently available on this site, and contributed by the community on the internet.

可以在 PHP REST 包装器示例中找到提供的所有代码。You can find all the code available in the PHP REST wrapper sample.

例如,创建客户端:For example, to create a client:

```php
$hub = new NotificationHub("connection string", "hubname");
```

发送 iOS 本机通知:To send an iOS native notification:

```php
$notification = new Notification("apple", '{"aps":{"alert": "Hello!"}}');
$hub->sendNotification($notification, null);
```

实现Implementation

如果尚未实现,按照入门教程学至最后一节,必须在此过程中实现后端。If you did not already, follow the Get started tutorial up to the last section where you have to implement the backend. 此外,如果你希望可以使用 PHP REST 包装器示例中的代码,可直接转到完成本教程部分。Also, if you want you can use the code from the PHP REST wrapper sample and go directly to the Complete the tutorial section.

有关实现完整 REST 包装器的所有详细信息,请访问 MSDNAll the details to implement a full REST wrapper can be found on MSDN. 本部分介绍了访问通知中心 REST 终结点所需的主要步骤的 PHP 实现:In this section, we describe the PHP implementation of the main steps required to access Notification Hubs REST endpoints:

  1. 解析连接字符串Parse the connection string
  2. 生成授权令牌Generate the authorization token
  3. 执行 HTTP 调用Perform the HTTP call

解析连接字符串Parse the connection string

下面是实现客户端的主类,其构造函数将解析连接字符串:Here is the main class implementing the client, whose constructor that parses the connection string:

```php
class NotificationHub {
    const API_VERSION = "?api-version=2013-10";

    private $endpoint;
    private $hubPath;
    private $sasKeyName;
    private $sasKeyValue;

    function __construct($connectionString, $hubPath) {
        $this->hubPath = $hubPath;

        $this->parseConnectionString($connectionString);
    }

    private function parseConnectionString($connectionString) {
        $parts = explode(";", $connectionString);
        if (sizeof($parts) != 3) {
            throw new Exception("Error parsing connection string: " . $connectionString);
        }

        foreach ($parts as $part) {
            if (strpos($part, "Endpoint") === 0) {
                $this->endpoint = "https" . substr($part, 11);
            } else if (strpos($part, "SharedAccessKeyName") === 0) {
                $this->sasKeyName = substr($part, 20);
            } else if (strpos($part, "SharedAccessKey") === 0) {
                $this->sasKeyValue = substr($part, 16);
            }
        }
    }
}
```

创建安全令牌Create a security token

有关安全令牌创建的详细信息,请访问 此处The details of the security token creation are available here. 以下方法必须添加到 NotificationHub 类,以便根据当前请求的 URI 和提取自连接字符串的凭据创建令牌。The following method has to be added to the NotificationHub class to create the token based on the URI of the current request and the credentials extracted from the connection string.

```php
private function generateSasToken($uri) {
    $targetUri = strtolower(rawurlencode(strtolower($uri)));

    $expires = time();
    $expiresInMins = 60;
    $expires = $expires + $expiresInMins * 60;
    $toSign = $targetUri . "\n" . $expires;

    $signature = rawurlencode(base64_encode(hash_hmac('sha256', $toSign, $this->sasKeyValue, TRUE)));

    $token = "SharedAccessSignature sr=" . $targetUri . "&sig="
                . $signature . "&se=" . $expires . "&skn=" . $this->sasKeyName;

    return $token;
}
```

发送通知Send a notification

首先,让我们定义表示通知的类。First, let us define a class representing a notification.

```php
class Notification {
    public $format;
    public $payload;

    # array with keynames for headers
    # Note: Some headers are mandatory: Windows: X-WNS-Type, WindowsPhone: X-NotificationType
    # Note: For Apple you can set Expiry with header: ServiceBusNotification-ApnsExpiry in W3C DTF, YYYY-MM-DDThh:mmTZD (for example, 1997-07-16T19:20+01:00).
    public $headers;

    function __construct($format, $payload) {
        if (!in_array($format, ["template", "apple", "windows",  "windowsphone"])) {
            throw new Exception('Invalid format: ' . $format);
        }

        $this->format = $format;
        $this->payload = $payload;
    }
}
```

此类是一个容器,其中包含本机通知正文或一组模板通知上的属性,以及一组包含格式(本机平台或模板)和平台特定属性(如 Apple 过期属性和 WNS 标头)的标头。This class is a container for a native notification body, or a set of properties on case of a template notification, and a set of headers, which contains format (native platform or template) and platform-specific properties (like Apple expiration property and WNS headers).

请参阅通知中心 REST API 文档和具体的通知平台格式,了解所有可用选项。Refer to the Notification Hubs REST APIs documentation and the specific notification platforms' formats for all the options available.

具备了此类后,我们现在可以在 NotificationHub 类中编写发送通知方法了:Armed with this class, we can now write the send notification methods inside of the NotificationHub class:

```php
public function sendNotification($notification, $tagsOrTagExpression="") {
    if (is_array($tagsOrTagExpression)) {
        $tagExpression = implode(" || ", $tagsOrTagExpression);
    } else {
        $tagExpression = $tagsOrTagExpression;
    }

    # build uri
    $uri = $this->endpoint . $this->hubPath . "/messages" . NotificationHub::API_VERSION;
    $ch = curl_init($uri);

    if (in_array($notification->format, ["template", "apple"])) {
        $contentType = "application/json";
    } else {
        $contentType = "application/xml";
    }

    $token = $this->generateSasToken($uri);

    $headers = [
        'Authorization: '.$token,
        'Content-Type: '.$contentType,
        'ServiceBusNotification-Format: '.$notification->format
    ];

    if ("" !== $tagExpression) {
        $headers[] = 'ServiceBusNotification-Tags: '.$tagExpression;
    }

    # add headers for other platforms
    if (is_array($notification->headers)) {
        $headers = array_merge($headers, $notification->headers);
    }

    curl_setopt_array($ch, array(
        CURLOPT_POST => TRUE,
        CURLOPT_RETURNTRANSFER => TRUE,
        CURLOPT_SSL_VERIFYPEER => FALSE,
        CURLOPT_HTTPHEADER => $headers,
        CURLOPT_POSTFIELDS => $notification->payload
    ));

    // Send the request
    $response = curl_exec($ch);

    // Check for errors
    if($response === FALSE){
        throw new Exception(curl_error($ch));
    }

    $info = curl_getinfo($ch);

    if ($info['http_code'] <> 201) {
        throw new Exception('Error sending notification: '. $info['http_code'] . ' msg: ' . $response);
    }
} 
```

以上方法将 HTTP POST 请求发送到通知中心的 /messages 终结点,该请求具有发送通知的正确正文和标头。The above methods send an HTTP POST request to the /messages endpoint of your notification hub, with the correct body and headers to send the notification.

完成教程Complete the tutorial

现在,可以通过从 PHP 后端发送通知来完成该入门教程。Now you can complete the Get Started tutorial by sending the notification from a PHP backend.

初始化通知中心客户端(按入门教程中所述替换连接字符串和中心名称):Initialize your Notification Hubs client (substitute the connection string and hub name as instructed in the Get started tutorial):

```php
$hub = new NotificationHub("connection string", "hubname");
```

然后,根据用户的目标移动平台添加发送代码。Then add the send code depending on your target mobile platform.

Windows 应用商店和 Windows Phone 8.1(非 Silverlight)Windows Store and Windows Phone 8.1 (non-Silverlight)

```php
$toast = '<toast><visual><binding template="ToastText01"><text id="1">Hello from PHP!</text></binding></visual></toast>';
$notification = new Notification("windows", $toast);
$notification->headers[] = 'X-WNS-Type: wns/toast';
$hub->sendNotification($notification, null);
```

iOSiOS

```php
$alert = '{"aps":{"alert":"Hello from PHP!"}}';
$notification = new Notification("apple", $alert);
$hub->sendNotification($notification, null);
```

Windows Phone 8.0 和 8.1 SilverlightWindows Phone 8.0 and 8.1 Silverlight

```php
$toast = '<?xml version="1.0" encoding="utf-8"?>' .
            '<wp:Notification xmlns:wp="WPNotification">' .
               '<wp:Toast>' .
                    '<wp:Text1>Hello from PHP!</wp:Text1>' .
               '</wp:Toast> ' .
            '</wp:Notification>';
$notification = new Notification("windowsphone", $toast);
$notification->headers[] = 'X-WindowsPhone-Target : toast';
$notification->headers[] = 'X-NotificationClass : 2';
$hub->sendNotification($notification, null);
```

Kindle FireKindle Fire

```php
$message = '{"data":{"msg":"Hello from PHP!"}}';
$notification = new Notification("adm", $message);
$hub->sendNotification($notification, null);
```

运行 PHP 代码,现在应该生成显示在目标设备上的通知。Running your PHP code should produce now a notification appearing on your target device.

后续步骤Next Steps

在本主题中,我们介绍了如何为通知中心创建简单的 Java REST 客户端。In this topic, we showed how to create a simple Java REST client for Notification Hubs. 从这里可以:From here you can:

  • 下载完整的 PHP REST 包装器示例,其中包含上述所有代码。Download the full PHP REST wrapper sample, which contains all the code above.
  • 在 [突发新闻教程] 中继续学习通知中心标记功能Continue learning about Notification Hubs tagging feature in the [Breaking News tutorial]
  • 在 [通知用户教程] 中了解如何将通知推送到单个用户Learn about pushing notifications to individual users in [Notify Users tutorial]

有关详细信息,另请参阅 PHP 开发人员中心For more information, see also the PHP Developer Center.