C言語から外部スクリプト(今回はPHP)をコールするようなプログラムを書いてみた

背景

PHPでいうところの execshell_exec のようなことがしたい。
Cだと system っていう関数があるんだけど、それだと返り値がわからない。
出力結果をファイルに出力して、それをCで読み込んで・・・ってのも考えたけど
ファイルがかぶってしまうといやなので、調べていたら popen という便利な関数があった。

$ man popen
popen() 関数は、プロセスをオープンする。パイプを生成し、フォークを行い、シェル起動する。

コード

これを使ってみたサンプルコードが↓

#include<stdio.h>
#include<string.h>

int main()
{
    char  str[512],*ptr;
    FILE  *fp;
    char* code= "php ./hoge.php";

    if((fp=popen(code,"r"))==NULL){
        fprintf(stderr,"error!!!\n");
        return 0;
    }
    while(1){
        fgets(str,512,fp);
        if(feof(fp)){
            break;
        }
        ptr=strchr(str,'\n');
        if(ptr!=NULL){
            *ptr='\0';
        }
        printf("%s\n",str);
    }
    pclose(fp);
    return 0;
}

hoge.php

<?php
    echo 'Hello World By PHP';
?>

実行

$ ./a.out
Hello World By PHP

よし!!

考察

どなたか、Cから外部スクリプトを呼ぶスマートな方法知らないですかね?
#条件としては、スクリプトの返り値をCに持ってこれること。

UAじゃなくブラウザを出し分ける

たいてい、ユーザーエージェントみて調べるのが手っ取り早いし簡単だと思うけど
ユーザーエージェント偽ってても大丈夫なようにブラウザ特有オブジェクトを使って
どのブラウザなのかを判別したい

まず知りたいのはIEなのかNN系なのかってーことですかね

if(document.all) { 
    //IE
} else if(document.layers || document.getElementById) { 
    //NN
} 

で、問題はその後。
FFのバージョンによって出し分けなければいけない場面があったので
1.5系と2.0系を出し分ける方法を調べてみた

if( window.innerWidth && !window.navigator.registerContentHandler) {
    //FireFox 1.5
} else {
    //FIreFox 2.0
}

そして、IE7はクソだけど、それにも対応しなくちゃいけないから、、、
これも判別してやったぜ、ちくしょう

if (typeof document.body.style.maxHeight != "undefined") {
  // IE 7
} else {
  // IE 6
}

おまけ

  1. オペラかどうか
  2. IEかどうか

だったら下記だけでわかるらしいお

window.opera
var isMSIE = /*@cc_on!@*/false;

なんでこれでIEかどうかわかるのかは謎。

Mac?シラネ

初体験

携帯からアップしてみたよ。


知り合いが携帯をソフトバンクモバイルからDoCoMoに乗り換えるらしい。
うん、正解だと思うよ。
なんでって、ちょっと山に入ると電波なくなるとか、ありえなさすぎ。

コマンドライン上じゃなくてPHPの中でやりたい

色々調べたけど、参考になりそうなのがなかった。

よくよく /usr/local/bin/curl の使い方を見てみたらあることに気づいて。

@filepath

ってつければいいんだ。

ってことでクラスを作ってみた。

<?php
class FileUploadByCurl
{
    private $_path = null;
    private $_url = null;
    private $_formName = null;
    private $_params = array();

    public function __construct($path, $url, $formName, $otherParams = array())
    {
        $this->_path = $path;
        $this->_url = $url;
        foreach($otherParams as $name => $value) {
            $this->_params[$name] = $value;
        }
        $this->_params[$formName] = '@'.$path;
    }

    public function __destruct()
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $this->_url );
        curl_setopt($ch, CURLOPT_POST, 1 );
        curl_setopt($ch, CURLOPT_POSTFIELDS, $this->_params);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $res = curl_exec($ch);

        if(curl_errno($ch)) {
            print curl_error($ch);
            die('Unable to upload file.');
        }
        curl_close($ch);

        return $res;
    }
}
?>

呼び出しサンプル

<?php
include('FileUploadByCurl.php');
$filename = '/tmp/hoge.jpg';
$url = 'http://hogehoge.com';
$formname = 'userfile'
$curlObj = new FileUploadByCurl($filename,$url,$formname);
?>

エラー処理なんてしてないけどね!!