NYCPHP Meetup

NYPHP.org

[nycphp-talk] PHP on Win.: Get Drive Letter for Current Script

Jayesh Sheth jayeshsh at ceruleansky.com
Sat Mar 12 10:34:45 EST 2005


Hello all,

I am trying to get PHP to co-operate when it comes to creating a CD- /
flash-drive-based catalog.

When a user pops in a CD or USB drive, the running PHP script should be
able to detect which drive letter it's on. Depending on how the eventual
application evolves, if the user chooses to install the catalog viewer on
another drive (say c:\ or d:\), the resulting PHP script(s) that are
copied to those drives need to know which drive they reside on (so some
configuration files with drive information in them can be written).

I was thinking of using the WinRar self extracting module to extract and
copy the files from CD (or from a download) onto the chosen drive. WinRar
can run a .bat or .exe file post-installation. In this case, it would be a
.bat file that runs a PHP script which writes configuration files with
information such as 'absolute path to htdocs subdirectory on this drive'
and so on.

Perhaps I need to use a better installer such as Nullsoft's installer
which might write customized files for me. But I was thinking: it is nicer
to initial setup in PHP, especially since it is not rocket science - it is
just figuring out on which drive the script is running, and the absolute
paths to various subdirectories, and then writing to those subdirectory.
You can get the relative path to the currently running script from $_ENV,
but not the path with a drive letter. (The HTTP server for the catalog
needs an absolute path.)

The $_ENV environment variable contains various reference to the
'homedrive', for example $_ENV['homedrive']. But what if the user chooses
to install the catalog viewer to d:\, or e:\ ? This information is not
provided by $_ENV.

I did some research, and came across the W32api functions:
http://us4.php.net/manual/en/ref.w32api.php

This extension enables you to call functions available in Windows dlls (or
other dlls) using PHP.

I also found a good article on the subject at PHP Architect (
https://www.phparch.com/issue.php?mid=5 ).

This article lists the following code snippet to get and display
information using the GetSystemInfo function from kernel32.dll. I looked
at Microsoft's API documentation on this subject (
http://msdn.microsoft.com/library/en-us/sysinfo/base/getsysteminfo.asp?frame=true
) but I could not find out how to use this function to determine the drive
letter on which the current script is running.

Does anyone know how to do this using the W32api extension or by any other
method?
One (convoluted) way to do this would be to let the script check for the
existence of a file on all drives, C - Z using is_file(). So it would
check for c:\myfile123.php, d:\myfile123.php, and so on. But this is not
the best way to do it. There has got to be a better way!

Here is the code I mentioned above (had to copy this from the PDF as the
code was for some reason not listed on disk):

1 <!&#151; HTML before dynamic content &#151;!>
2 <html>
3 <head>
4 <title>Windows System Information</title>
5 </head>
6 <body>
7 <h1>Windows System Information</h1>
8 <table border="1">
9 <th>Property</th>
10 <th>Value</th>
11 <!&#151; Begin dynamic content &#151;!>
12 <?php
13
14 // Since we are using a scalar to hold the value of the SYSTEM_INFO
type, no
15 // types need to be defined or enumerated.
16
17 // Register Windows API functions
18
19 w32api_register_function("kernel32.dll", "GetSystemInfo", "bool");
20 w32api_register_function("kernel32.dll", "GetSystemDirectoryA", "long");
21 w32api_register_function("kernel32.dll", "GetVersion", "long");
22
23 // Build an array of all elements in a SYSTEM_INFO type
24
25 $type_elements=array("dwOemID", "dwPageSize",
"lpMinimumApplicationAddress",
26 "lpMaximumApplicationAddress", "dwActiveProcessorMask",
27 "dwNumberOfProcessors", "dwProcessorType",
28 "dwAllocationGranularity", "dwReserved");
29
30 // Space out the buffer to allow it to hold the contents of a
SYSTEM_INFO type
31
32 $buf=str_repeat(' ', 255);
33
34 GetSystemInfo($buf);
35
36 // Loop through each element of the type, building a format string
37
38 $first_element=true;
39 for ($i=0; $i<sizeof($type_elements); $i++) {
40 if (!$first_element)
41 $unpack_str .= "/";
42 else
43 $unpack_str="";
44 $unpack_str .= "l" . $type_elements[$i];
45 $first_element=false;
46 }
47
48 // Unpack the SYSTEM_INFO type
49 $arr=unpack($unpack_str, $buf);
50
51 // Loop through each element of the type, displaying its value in a
HTML table
52
53 for ($i=0; $i<sizeof($type_elements); $i++) {
54 echo "<tr><td>" . $type_elements[$i] . "</td><td>" .
55 $arr[$type_elements[$i]] . "</td></tr>\n";
56 }
57
58 // Space out a buffer again for use with GetSystemDirectoryA()
59
60 $buf=str_repeat(' ', 64);
61
62 // Run our other Windows API functions and display their results in a
HTML table
63 GetSystemDirectoryA($buf, strlen($buf));
64
65 echo "<td>SystemDirectory</td><td>" . $buf . "</td></tr>\n";
66
67 echo "<tr><td>Version</td><td>" . GetVersion() . "</td></tr>\n";
68
69 ?>
70 <!&#151; End dynamic content &#151;!>
71 </table>
72 </body>
73 </html>



More information about the talk mailing list