1

私はソケットから読み取るコードに取り組んでいますが、特定の大きな入力を取得するとうまくいきません。修正する前に、このための単体テストを追加しましたが、モックできないためにスタックしました(および、、など、fread使用している他のPHP組み込み関数)。fsockopenfeof

簡単に言えば、私の問題は、このコードが「致命的なエラー:fgets()を再宣言できません...」で失敗することです。

function fgets($fp){
return "xxx";
}

実際のコードで使用するソケットラッパークラスを作成してから、そのラッパークラスのモックオブジェクトを作成できることに気付きました。しかし、それは犬を振る尾であり、私はそれが物事の原則を超えて悪い考えである理由を考えることができます。(たとえば、コードをより複雑で効率的にし、まだテストされていないコードをリファクタリングする必要があります。)

fgets()だから、私の質問は、単体テスト内で、組み込みの実装を自分のものに置き換えるにはどうすればよいですか?(または、ボックスの外側を考えたい場合、質問は次のように表現できます:呼び出しからの戻り値はいつですか?への呼び出しがfgets($socket)返す文字列をどのように制御できますか?)$socketfsockopen


傍白

正解で必要とされるapdのインストールは、大変な作業です。これは2004年に最後にリリースされ、そのままではphp5.3をサポートしていません。そのためのUbuntuパッケージはなく、pecl install apd失敗しました。それで、これをインストールする手順は次のとおりです(これらはubuntu 10.04用です)(すべてrootとして実行されます):

pecl download apd
tar xzf apd-1.0.1.tgz
cd apd-1.0.1
phpize
./configure
# Do edits (see below)
make install

実行する必要のあるパッチについては、https://bugs.php.net/bug.php?id=58798を参照してください。NB。実際に変更する必要がある行は1つだけなので、次のように手動で行うことができます。テキストエディタでphp_apd.cを開き、967行に移動して、CG(extended_info) = 1この行を次の行に置き換えます。

CG(compiler_options) |= ZEND_COMPILE_EXTENDED_INFO;

最後に、php.iniエントリを追加してアクティブ化する必要があります。http://php.net/manual/en/apd.installation.phpを参照してください

4

4 に答える 4

3

APDまたはRunkitにアクセスできないが、名前空間を使用している場合は、次のことを試してください:https ://stackoverflow.com/a/5337635/664108 (リンクの回答はtime()を指しますが、違いはありません)

于 2012-07-05T09:09:18.077 に答える
1

に変更fsockopenfopenてモックを実行し、他の機能は変更しないでください。

$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);

$fp = fopen("/path/to/your/dummy_data_file");
于 2012-07-01T08:19:34.683 に答える
0

override_function を使用して目的の目標を達成する方法を示す完全に機能するコードを含む私の経験についてブログに書きました。ファイルの読み取りとソケットの読み取りの両方。ここでその記事全体を繰り返すことはしませんが、関数をどのように使用する必要があるかを指摘するだけです。

  1. rename_function古い元の関数に名前を付けて、後で見つけられるようにするために使用します。
  2. override_function新しい動作を定義するために使用します
  3. rename_functionにダミーの名前を付けるために使用します__overridden__

後で元の動作を復元できるようにする場合は、手順 1 が重要です。

最後の「思考の糧」セクションでは、より堅牢であると思われる代替アプローチを示します。したがって、phpUnit を使用する場合は、ファイル関数を置き換える方が安全だと思います。デフォルトの動作が組み込み関数に転送される永続的な関数置換を作成します。次に、パラメーター (この場合はリソース) をチェック$handleして、別の動作が必要なストリームで呼び出されているかどうかを判断します。(これは、Chain Of Responsibility 設計パターンの例と言えると思います。)

于 2012-07-02T02:48:27.663 に答える