Edit report at http://bugs.php.net/bug.php?id=52647&edit=1
ID: 52647
Updated by: kalle@php.net
Reported by: shaun dot spiller at yahoo dot com
Summary: Function to get Windows drive letters
Status: Assigned
Type: Feature/Change Request
Package: *Directory/Filesystem functions
Operating System: Windows
PHP Version: 5.3.3
Assigned To: pajoye
Block user comment: N
New Comment:
That was what I was thinking too, something like sys_get_drives() or
sys_get_devices() was what I had in mind if someone one day was going to
port it so the name is consistent :)
Previous Comments:
------------------------------------------------------------------------
[2010-08-19 22:26:08] pajoye@php.net
Sorry Kalle, already looked at that a while back. Also the function name
and co is not that good. >> taking back :)
------------------------------------------------------------------------
[2010-08-19 22:24:10] kalle@php.net
I'm re-assigning this one to me, I'll have a look and test of it doing
the weekend and commit it to trunk
Thanks for the contribution! :)
------------------------------------------------------------------------
[2010-08-19 19:57:30] shaun dot spiller at yahoo dot com
Thank you for the response (no, really, it took ages to figure out how
to submit this because I couldn't get the mailing lists to work).
My reasoning in the non-Windows implementation was that (like in Java)
it should provide a consistent way to traverse the entire file tree
without needing to know or care about the OS, whether it's Windows,
*n*x, or something completely alien. It also allows for hypothetical
future arrangements of filesystems (even if they are unlikely).
------------------------------------------------------------------------
[2010-08-19 19:41:04] johannes@php.net
I think this is useful for Windows but I'm not sure the non-Windows
implementation is useful. I think I would disable the function on other
platforms.
Assigning to Pierre.
------------------------------------------------------------------------
[2010-08-19 19:10:16] shaun dot spiller at yahoo dot com
Description:
------------
Hello developers
I realised recently that PHP has no function to determine the available
drive letters on Windows. As far as I can tell it's not possible to get
such a list with the standard filesystem functions without generating
errors for missing letters and waking up all other drives, which is, at
best, extremely inefficient.
I've written a function called filesys_get_roots, modelled after Java's
File.listRoots():
http://java.sun.com/javase/6/docs/api/java/io/File.html#listRoots%28%29
It returns an array, which on Windows looks like this (for example):
array(7) {
[0]=>
string(3) "A:\"
[1]=>
string(3) "C:\"
[2]=>
string(3) "D:\"
[3]=>
string(3) "E:\"
[4]=>
string(3) "F:\"
[5]=>
string(3) "G:\"
[6]=>
string(3) "M:\"
}
And on other platforms, like this:
array(1) {
[0]=>
string(1) "/"
}
I don't know how to properly propose/submit/include the code.
I've made a diff against the PHP 5.3.3 sources, if that helps:
======================================
diff -rc php-5.3.3-orig/ext/standard/basic_functions.c
php-5.3.3/ext/standard/basic_functions.c
*** php-5.3.3-orig/ext/standard/basic_functions.c Thu May 13 03:13:30
2010
--- php-5.3.3/ext/standard/basic_functions.c Tue Aug 17 16:34:40 2010
***************
*** 1249,1254 ****
--- 1249,1257 ----
ZEND_BEGIN_ARG_INFO(arginfo_sys_get_temp_dir, 0)
ZEND_END_ARG_INFO()
+
+ ZEND_BEGIN_ARG_INFO(arginfo_filesys_get_roots, 0)
+ ZEND_END_ARG_INFO()
/* }}} */
/* {{{ filestat.c */
ZEND_BEGIN_ARG_INFO(arginfo_disk_total_space, 0)
***************
*** 3078,3083 ****
--- 3081,3087 ----
PHP_FE(file, arginfo_file)
PHP_FE(file_get_contents, arginfo_file_get_contents)
PHP_FE(file_put_contents, arginfo_file_put_contents)
+ PHP_FE(filesys_get_roots, arginfo_filesys_get_roots)
PHP_FE(stream_select, arginfo_stream_select)
PHP_FE(stream_context_create, arginfo_stream_context_create)
PHP_FE(stream_context_set_params, arginfo_stream_context_set_params)
diff -rc php-5.3.3-orig/ext/standard/file.c
php-5.3.3/ext/standard/file.c
*** php-5.3.3-orig/ext/standard/file.c Sun May 2 21:11:22 2010
--- php-5.3.3/ext/standard/file.c Tue Aug 17 17:38:30 2010
***************
*** 2539,2544 ****
--- 2539,2570 ----
}
/* }}} */
+ /* {{{ proto string filesys_get_roots()
+ Returns a list of the filesystem roots */
+ PHP_FUNCTION(filesys_get_roots)
+ {
+ #ifdef PHP_WIN32
+ DWORD drives = GetLogicalDrives();
+ char temp[3] = "?:\\";
+ int i;
+
+ array_init(return_value);
+
+ for (i = 0; i < 26; i++) {
+ if (drives & 1) {
+ temp[0] = 'A' + i;
+ add_next_index_stringl(return_value, temp, 3, 1);
+ }
+ drives >>= 1;
+ if (!drives) break;
+ }
+ #else
+ array_init(return_value);
+ add_index_string(return_value, 0, "/", 1);
+ #endif
+ }
+ /* }}} */
+
/*
* Local variables:
* tab-width: 4
diff -rc php-5.3.3-orig/ext/standard/file.h
php-5.3.3/ext/standard/file.h
*** php-5.3.3-orig/ext/standard/file.h Sun Jan 3 09:23:28 2010
--- php-5.3.3/ext/standard/file.h Tue Aug 17 16:34:46 2010
***************
*** 69,74 ****
--- 69,75 ----
PHP_NAMED_FUNCTION(php_if_ftruncate);
PHP_NAMED_FUNCTION(php_if_fstat);
PHP_FUNCTION(sys_get_temp_dir);
+ PHP_FUNCTION(filesys_get_roots);
PHP_MINIT_FUNCTION(user_streams);
======================================
I've also written a documentation page:
======================================
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xmlns="http://docbook.org/ns/docbook"
xml:id="function.filesys-get-roots">
<refnamediv>
<refname>filesys_get_roots</refname>
<refpurpose>Returns a list of the filesystem roots</refpurpose>
</refnamediv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<type>array</type><methodname>filesys_get_roots</methodname>
<void/>
</methodsynopsis>
<para>
Returns an array listing the filesystem root directories. Unix-like
systems have a single root directory ("/"). Windows systems have one
or more independent drive letters ("A:\", "C:\", "D:\", etc.).
</para>
<para>
On Windows the function returns all drive letters present in the
context
of the user that runs PHP. It does not attempt to determine whether
drives
are ready for use (e.g., whether they have a disk in).
</refsect1>
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
The function returns an array of strings identifying the filesystem
roots,
including the trailing "/" or "\".
</para>
</refsect1>
<refsect1 role="examples">
&reftitle.examples;
<para>
<example>
<title><function>filesys_get_roots</function> example</title>
<programlisting role="php">
<![CDATA[
<?php
$roots = filesys_get_roots();
var_dump($roots);
?>
]]>
</programlisting>
On a Unix system, the above example will output:
<screen>
<![CDATA[
array(1) {
[0]=>
string(1) "/"
}
]]>
</screen>
On Windows, the above example will output something similar to:
<screen>
<![CDATA[
array(4) {
[0]=>
string(3) "A:\"
[1]=>
string(3) "C:\"
[2]=>
string(3) "D:\"
[3]=>
string(3) "E:\"
}
]]>
</screen>
</example>
</para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->
======================================
Help me?! :)
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/bug.php?id=52647&edit=1