nazolabo

なぞさんのブログ

携帯版Google AdSenseのPHPコードがきもいので修正してみた

allow_url_fopen強制っすか!Notice出しまくりっすか!GLOBAL汚染しまくりっすか!みたいな感じなので修正ついでにクラス化してみた。
とりあえずHTTP_Requestで通信するようにしてみたけど、他のがよければ他のに書き換えるといいと思います。

<?php

/**
 * Copyright (C) 2007 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     @license http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

require_once "HTTP/Request.php";

class GoogleMobileAdSense {
  
  var $google_dt;
  var $options;
  
  function GoogleMobileAdSense() {
    $this->google_dt = time();
    $this->options = array();
  }
  
  function google_append_url(&$url, $param, $value) {
    $url .= "&" . $param . "=" . urlencode($value);
  }
  
  function google_append_globals(&$url, $param) {
    $this->google_append_url($url, $param, $this->options[$param]);
  }
  
  function google_append_color(&$url, $param) {
    $color_array = split(",", $this->options[$param]);
    $this->google_append_url($url, $param,
                      $color_array[$this->google_dt % sizeof($color_array)]);
  }
  
  function google_get_ad_url() {
    $google_ad_url = "http://pagead2.googlesyndication.com/pagead/ads?";
    $google_scheme = ($this->options["https"] == "on")
        ? "https://" : "http://";
    foreach ($this->options as $param => $value) {
      if ($param == "client") {
        $this->google_append_url($google_ad_url, $param,
                          "ca-mb-" . $this->options[$param]);
      } else if (strpos($param, "color_") === 0) {
        $this->google_append_color($google_ad_url, $param);
      } else if ((strpos($param, "host") === 0)
                 || (strpos($param, "url") === 0)) {
        $this->google_append_url($google_ad_url, $param,
                          $google_scheme . $this->options[$param]);
      } else {
        $this->google_append_globals($google_ad_url, $param);
      }
    }
    $this->google_append_url($google_ad_url, "dt", 
     		    round(1000 * array_sum(explode(" ", microtime()))));
    
    return $google_ad_url;
  }
  
  /*
   * 広告を取得する
   */
  function get($options) {
    $this->options = $options;
    
    $req =& new HTTP_Request($this->google_get_ad_url());
    if (!PEAR::isError($req->sendRequest())) {
      return $req->getResponseBody();
    }
    
    return '';
  }
  
  /*
   * $_SERVERの値を取得する(存在しないキーを指定するとNoticeが出る対策用)
   */
  function getServerVar($name) {
    if (array_key_exists($name, $_SERVER)) {
      return $_SERVER[$name];
    }
    
    return null;
  }
}

使い方例

<?php

require('GoogleMobileAdSense.php');

$google = new GoogleMobileAdSense();

$options = array();
$options['ad_type']='text';
$options['channel']='xxxxxxxx';
$options['client']='xxxxxxxx';
$options['format']='mobile_single';
$options['https']=$google->getServerVar('HTTPS');
$options['host']=$google->getServerVar('HTTP_HOST');
$options['ip']=$google->getServerVar('REMOTE_ADDR');
$options['markup']='xhtml';
$options['oe']='utf8';
$options['output']='xhtml';
$options['ref']=$google->getServerVar('HTTP_REFERER');
$options['url']=$google->getServerVar('HTTP_HOST') . $google->getServerVar('REQUEST_URI');
$options['useragent']=$google->getServerVar('HTTP_USER_AGENT');

$ad = $google->get($options);

?>

<html>
<body>

<?php echo $ad ?>

</body>
</html>

ちなみに試してみたのですが、広告が表示されるまでやや時間がかかるようなので、正常動作してるかはわかりません。UserAgentが携帯のものじゃないと出ないようです。→不明
あとAdSenseが仕様変更した場合は保証しません。

はてブへの返信

2007年10月11日 koyhoge koyhoge php, google オリジナルのコードってどこにあるん?

AdSensePHPのコードを生成すると、

require('http://pagead2.googlesyndication.com/pagead/show_ads.php');

こういう行があると思います。このファイルがオリジナルです。

追記

若干勘違いしてたのですが、どちらかというと問題なのはallow_url_fopenよりallow_url_includeが強制なことで、allow_url_fopen無しでHTTP通信しようとするとPEARのライブラリを使うかcurlを使うかsocketで生通信するかしかなくなるので、allow_url_fopenはデフォルトでOnなのでまあいいかなーって気もします。
どちらかというとallow_url_includeが強制なのはいろいろとまずい(そもそも最近のPHPはデフォルトでOff)と思うので、それだけの対策なら元のコードをダウンロードして手元に置けばいいだけの話です。Noticeは気持ち悪いですが、特に海外のPHPコードはNoticeを平気で出すものが多いので、諦めるしかないかもしれません。(でもこれって日本専用じゃ?)
元のコードはこれはこれで、「簡単なコードを貼り付けるだけで広告が表示される」という設計を考えるとこうなるのは仕方ないのかなという気もします。

追記2(2007-12-13)

今見たら出力コードに別ファイルになってたコードが埋め込まれてました。(早い話がallow_url_includeが関係なくなった)