Skip to content

Commit 2d0f432

Browse files
author
Ilia Alshanetsky
committed
Added scandir() function, which allows quick retrieval of all files &
directories within the specified path and sort the output in alphabetical or reverse alphabetical order.
1 parent 38a3f33 commit 2d0f432

File tree

3 files changed

+77
-0
lines changed

3 files changed

+77
-0
lines changed

ext/standard/basic_functions.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,7 @@ function_entry basic_functions[] = {
724724
PHP_FE(rewinddir, NULL)
725725
PHP_STATIC_FE("readdir", php_if_readdir, NULL)
726726
PHP_FALIAS(dir, getdir, NULL)
727+
PHP_FE(scandir, NULL)
727728
#ifdef HAVE_GLOB
728729
PHP_FE(glob, NULL)
729730
#endif

ext/standard/dir.c

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@
3939
#include "win32/readdir.h"
4040
#endif
4141

42+
#if !HAVE_ALPHASORT || !HAVE_SCANDIR
43+
#include "php_scandir.h"
44+
#endif
45+
4246
#ifdef HAVE_GLOB
4347
#ifndef PHP_WIN32
4448
#include <glob.h>
@@ -422,6 +426,77 @@ PHP_FUNCTION(glob)
422426
/* }}} */
423427
#endif
424428

429+
/* {{{ php_alphasortr
430+
*/
431+
static int php_alphasortr(const struct dirent **a, const struct dirent **b)
432+
{
433+
return strcoll((*b)->d_name, (*a)->d_name);
434+
}
435+
/* }}} */
436+
437+
/* {{{ proto array scandir(string dir [, int sorting_order])
438+
List files & directories inside the specified path */
439+
PHP_FUNCTION(scandir)
440+
{
441+
char *dirn;
442+
int dirn_len;
443+
int flags = 0;
444+
char *path;
445+
struct dirent **namelist;
446+
int n, i;
447+
448+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &dirn, &dirn_len, &flags) == FAILURE) {
449+
return;
450+
}
451+
452+
#ifdef ZTS
453+
if(!IS_ABSOLUTE_PATH(dirn, dirn_len)) {
454+
path = expand_filepath(dirn, NULL TSRMLS_CC);
455+
} else
456+
#endif
457+
path = dirn;
458+
459+
if (PG(safe_mode) && (!php_checkuid(path, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
460+
RETVAL_FALSE;
461+
goto err;
462+
}
463+
if(php_check_open_basedir(path TSRMLS_CC)) {
464+
RETVAL_FALSE;
465+
goto err;
466+
}
467+
468+
if (!flags) {
469+
n = scandir(path, &namelist, 0, alphasort);
470+
} else {
471+
n = scandir(path, &namelist, 0, php_alphasortr);
472+
}
473+
474+
if (n < 0) {
475+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "(errno %d): %s", errno, strerror(errno));
476+
RETVAL_FALSE;
477+
goto err;
478+
}
479+
480+
array_init(return_value);
481+
482+
for (i = 0; i < n; i++) {
483+
add_next_index_string(return_value, namelist[i]->d_name, 1);
484+
free(namelist[i]);
485+
}
486+
487+
if (n) {
488+
free(namelist);
489+
}
490+
491+
err:
492+
if (path && path != dirn) {
493+
efree(path);
494+
}
495+
496+
return;
497+
}
498+
/* }}} */
499+
425500
/*
426501
* Local variables:
427502
* tab-width: 4

ext/standard/php_dir.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,6 @@ PHP_FUNCTION(rewinddir);
3535
PHP_NAMED_FUNCTION(php_if_readdir);
3636
PHP_FUNCTION(getdir);
3737
PHP_FUNCTION(glob);
38+
PHP_FUNCTION(scandir);
3839

3940
#endif /* PHP_DIR_H */

0 commit comments

Comments
 (0)