# 如何在微信或给到APP中打开点评APP

> 作者：James Zhu (<fatindeed@hotmail.com>)
>
> 创建日期：2018-03-28

## 引言

由于点评业务的需要，支付请求是在点评APP内发起的，因此需要在不同场景下打开点评APP。如

* 点评账号绑定完成后打开点评APP去消费
* 1楼咖啡吧提供一个二维码，让用户直接扫码买单

那么如何打开点评APP呢？我们可以通过**URL Schemes**来实现。

## URL Schemes

常见的**URL Schemes**有：

* <http://ciicpr.guanaitong.com/>
* tel://33352634
* sms\://13601873601
* mailto:<james.zhu@guanaitong.com>

而对于已安装点评APP的手机，其注册了`dianping://`这个scheme，打开点评APP首页的方法为`dianping://home`。

然而，在微信中，因为软件限制，我们无法在关爱通页面直接写一个`dianping://home`的链接来打开点评APP，必须通过点评的一个推广系统（可能微信为这个域名设置了白名单）。例如，`http://evt.dianping.com/synthesislink/19043.html`。

实际使用过程中，遇到了以下几个问题：

1. 如何找到打开`dianping://home`的页面？
2. 如何找到打开指定商家的页面？
3. [安卓下载链接已失效](http://jira.wuxingdev.cn/browse/DAILY-1296)，如何找到可用的安卓下载链接页面？

因此，我写了一个`dianping-spider.php`来枚举抓取*evt.dianping.com*下的页面，获取每个页面对应的scheme。

```php
define('SQL_CREATE_TABLE', 'CREATE TABLE IF NOT EXISTS Link (
    id    INTEGER PRIMARY KEY,
    link1 VARCHAR (255),
    protocol1 VARCHAR (30),
    link2 VARCHAR (255),
    protocol2 VARCHAR (30),
    link3 VARCHAR (255),
    protocol3 VARCHAR (30)
)');
define('SQL_INSERT_DATA', 'INSERT INTO Link (id, link1, protocol1, link2, protocol2, link3, protocol3) VALUES (:id, :link1, :scheme1, :link2, :scheme2, :link3, :scheme3)');

// Ctrl-C handler
pcntl_signal(SIGINT, function() {
    echo PHP_EOL.'finish at #'.$GLOBALS['i'].PHP_EOL;
    exit();
});

try {
    $dbh = new PDO('sqlite:dianping.db');
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $dbh->exec(SQL_CREATE_TABLE);
    $sth = $dbh->query('SELECT id from Link ORDER BY id DESC LIMIT 1');
    $lastId = $sth->fetchColumn();
    if($lastId == false) {
        $lastId = 3000;
    }
    else {
        $lastId++;
    }
    $stmt = $dbh->prepare(SQL_INSERT_DATA);
    echo 'start from #'.$lastId.PHP_EOL;
    for($i = $lastId; $i < $lastId + 1000; $i++) {
        pcntl_signal_dispatch();
        $content = file_get_contents('http://evt.dianping.com/synthesislink/'.$i.'.html');
        if($content && preg_match_all('/openLink_\d = "(.*)",/iU', $content, $matches)) {
            $links = $matches[1];
            $schemes = array_map(function($v) {
                $offset = strpos($v, '?');
                return ($offset !== false ? substr($v, 0, $offset) : $v);
            }, $links);
            $stmt->execute(array(
                ':id' => $i,
                ':link1' => $links[0],
                ':scheme1' => $schemes[0],
                ':link2' => $links[1],
                ':scheme2' => $schemes[1],
                ':link3' => $links[2],
                ':scheme3' => $schemes[2]
            ));
        }
    }
    echo 'finish at #'.$i.PHP_EOL;
} catch(PDOException $e) {
    echo $e->getMessage();
}
```

## 常用页面

* [dianping://home](http://evt.dianping.com/synthesislink/19043.html)
* [dianping://shopinfo](http://evt.dianping.com/synthesislink/19009.html)
