dir関数の詳細を調べてみた

dir関数の引数で指定したディレクトリに読み取り権限がなかった場合、falseが返ってくるのですが、この挙動についてPHPのソースを確認してみました。

該当するのは、/ext/standard/dir.cです。
PHP-5.2.9のソースで確認)

203行目から、以下のような部分があります。

static void _php_do_opendir(INTERNAL_FUNCTION_PARAMETERS, int createobject)
{
    char *dirname;
    int dir_len;
    zval *zcontext = NULL;
    php_stream_context *context = NULL;
    php_stream *dirp;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &dirname, &dir_len, &zcontext) == FAILURE) {
        RETURN_NULL();
    }

    if (zcontext) {
        context = php_stream_context_from_zval(zcontext, 0);
    }
    
    dirp = php_stream_opendir(dirname, ENFORCE_SAFE_MODE|REPORT_ERRORS, context);

    if (dirp == NULL) {
        RETURN_FALSE;
    }

    dirp->flags |= PHP_STREAM_FLAG_NO_FCLOSE;
        
    php_set_default_dir(dirp->rsrc_id TSRMLS_CC);

    if (createobject) {
        object_init_ex(return_value, dir_class_entry_ptr);
        add_property_stringl(return_value, "path", dirname, dir_len, 1);
        add_property_resource(return_value, "handle", dirp->rsrc_id);
        php_stream_auto_cleanup(dirp); /* so we don't get warnings under debug */
    } else {
        php_stream_to_zval(dirp, return_value);
    }
}
/* }}} */

/* {{{ proto mixed opendir(string path[, resource context])
   Open a directory and return a dir_handle */
PHP_FUNCTION(opendir)
{
    _php_do_opendir(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
}
/* }}} */

/* {{{ proto object dir(string directory[, resource context])
   Directory class with properties, handle and class and methods read, rewind and close */
PHP_FUNCTION(getdir)
{
    _php_do_opendir(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
}

※dir()関数は、getdir()のエイリアスとして定義されていました。コンストラクタぽく見せるためでしょうか・・・。

opendir()関数を呼び出した場合は、内部的には_php_do_opendir()を2番目の引数を0で呼び、dir()関数を呼び出した場合は、内部的には_php_do_opendir()を2番目の引数を1で呼び出すようです。

_php_do_opendirの2番目の引数の違いは、戻り値としてオブジェクトを返すのかどうかという点だけのようで、その前のエラーチェックは2つとも同様ですね。

なので、dir()関数に読み取り権限のないディレクトリを指定した場合は、opendir()関数の場合と同じようにfalseが返る仕様、と考えて問題なさそうです。




まあ、今まではopendir()などを使っていたので、dir()という関数や似非ディレクトリオブジェクトがあるというのを、今日初めて知ったんですけどね・・・!