PHP glob - listing folders. How I dealt with theft… with php Hasty listing php
Reg.ru: domains and hosting
The largest registrar and hosting provider in Russia.
Over 2 million domain names in service.
Promotion, mail for domain, solutions for business.
More than 700 thousand customers around the world have already made their choice.
*Mouseover to pause scrolling.
Back forward
Getting a list of folders with PHP
Listing directories using PHP, or listing directories
We will refer to a directory listing as a general query that lists all or some of the files and directories in a parent directory - a process similar to the index page provided by most web servers, but with O greater control over the content and its formatting.
Another advantage of this script is the ability to perform certain actions on files using PHP. In any case, the first step we need to take is to query the file system to return a list of files and directories.
The functions below allow you to retrieve filenames and other properties from a specific directory, or iterate through subcategories recursively.
Comment: PHP5 has a function scandir, which "returns a list of files and directories within a directory, at the given path", but it does not display any additional information about the files within the directory.
Single directory listing
First, here is an example of a simple function that returns a list of files, directories, and their properties, from a single directory (more advanced versions of this function can be found later in this tutorial.)
read())) ( // skip hidden files if($entry == ".") continue; if(is_dir("$dir$entry")) ( $retval = array("name" => "$dir$ entry/", "size" => 0, "lastmod" => filemtime("$dir$entry")); ) elseif(is_readable("$dir$entry")) ( $retval = array("name" = > "$dir$entry", "size" => filesize("$dir$entry"), "lastmod" => filemtime("$dir$entry")); ) ) $d->close(); return $retval; ) ?>
You can use this function like below:
The return value is an associative array of files, including file path information, size, and last modification date, unless the file is a directory, in which case the string "(dir)" occurs instead of the file's size.
Example 1:
",print_r($dirlist),""; /* sample output Array ( => Array ( => images/background0.jpg => image/jpeg => 86920 => 1077461701) => ...) */ ?>
Example 2:
",print_r($dirlist),""; /* sample output Array ( => Array ( => ./images/background0.jpg => image/jpeg => 86920 => 1077461701) => ...) */ ?>
Listing files via HTML
To get the output results on the page in HTML, we loop through the returned array through a loop
\n"; echo "
This code is quite easy to modify, for example:
- - display listing results in a list instead of a table;
- - make file names active links;
- - replace names with icons based on what type the file has;
- etc.
For example, to output only PNG files, add a simple condition to the output loop:
\n"; echo "
This example will skip and hide all files whose names end with .png. You can also apply additional terms based on file type, size, or last modified date.
If, for example, you want to display a thumbnail, a link to a larger image, or even a video, just give these 2 files the same names and in the script above use str_replace or a similar function to modify the contents of links.
Recursive directory listing
And since we've come this far, there will only be minor changes to the recursive list call function and subcategories. By adding a second parameter to the function, we retain the previous functionality of listing a single directory.
read())) ( // skip hidden files if($entry == ".") continue; if(is_dir("$dir$entry")) ( $retval = array("name" => "$dir$ entry/", "size" => 0, "lastmod" => filemtime("$dir$entry")); if($recurse && is_readable("$dir$entry/")) ( $retval = array_merge($ retval, getFileList("$dir$entry/", true)); ) ) elseif(is_readable("$dir$entry")) ( $retval = array("name" => "$dir$entry", "size " => filesize("$dir$entry"), "lastmod" => filemtime("$dir$entry")); ) ) $d->close(); return $retval; ) ?>
For the new functionality to work, you need to enter a value true(or 1) as the second parameter.
Before recursing the script, check if the subdirectories are readable and also read the last paragraph of this lesson in order to avoid access errors.
As before, the return value is an array, associative of arrays. In fact, the only addition is another extra option for recursive listing.
Recursion Depth Limit
This final example adds another property - the ability to determine how "deep" the recursion should go. The previous code will continue to explore nested directories until they run out. This script will help set the limit on the number of levels of nested directories.
read())) ( // skip hidden files if($entry == ".") continue; if(is_dir("$dir$entry")) ( $retval = array("name" => "$dir$ entry/", "size" => 0, "lastmod" => filemtime("$dir$entry")); if($recurse && is_readable("$dir$entry/")) ( if($depth == = false) ( $retval = array_merge($retval, getFileList("$dir$entry/", true)); ) elseif($depth > 0) ( $retval = array_merge($retval, getFileList("$dir$entry /", true, $depth-1)); ) ) ) elseif(is_readable("$dir$entry")) ( $retval = array("name" => "$dir$entry", "size" => filesize("$dir$entry"), "lastmod" => filemtime("$dir$entry")); ) ) $d->close(); return $retval; ) ?>
As before, we added only 1 new parameter and a couple of lines of code. If the default value for the recursion depth is not set, it is set to false. This allows us to be sure that the previous features remain and subsequent code will not "break" when the function is changed.
Cameron Laird
PHP does not support stream processing. Despite this, and contrary to what most PHP developers I talk to think, PHP applications can be multitasking. Let's start by clarifying what "multitasking" and "threading" mean for PHP programming.
Manifold concurrency
Let us first put aside the cases that lie outside the channel of the main theme. PHP has a complicated relationship with multitasking or concurrency. At the top level, PHP is constantly involved in multitasking - the standard PHP installations on the server (such as the Apache module) are used in a multitasking way. That is, multiple client applications (Web browsers) can request the same PHP page at the same time, and the Web server will return it to all more or less at the same time.
One Web page does not block the transmission of another, although they can interfere with each other a little when dealing with such limited resources as server memory or network bandwidth. Thus, the system requirement for concurrency may well allow for PHP-based solutions. In implementation terms, PHP makes the Web server responsible for concurrency.
Client side concurrency called Ajax has also caught the attention of developers in the last few years. Although the meaning of Ajax has become somewhat obscure, one aspect of this technology is that the browser can perform calculations simultaneously and remain sensitive to user actions such as menu selections. It's really kind of multitasking. PHP-coded Ajax does this, but without any special PHP involvement; Ajax frameworks for other languages work the same way.
A third example of concurrency that only scratches the surface of PHP is PHP/TK. PHP/TK is a PHP extension that provides portable Graphical User Interface (GUI) bindings to the PHP core. PHP/TK allows you to create desktop GUI applications written in PHP. Its event-based aspects model a form of concurrency that is easy to learn and less error prone than threading. Again, parallelism is "inherited" from additional technology, not a fundamental feature of PHP.
There have been several experiments to add threading support to PHP itself. As far as I know, none have been successful. However, the event-driven Ajax and PHP/TK frameworks show that events can better express concurrency for PHP than threads can. PHP V5 proves it.
PHP V5 offers stream_select()
In standard PHP V4 and earlier, all the work of a PHP application must be done sequentially. If the program needs to extract the price of a product from two commercial sites, for example, it asks for the first price, waits for a response, asks for a second price, and waits again.
What if the program could perform multiple tasks at the same time? It would complete in only a fraction of the time needed for sequential work.
First example
The new stream_select function, along with a few of its friends, provides this capability. Consider the following example:
0) ( $s=stream_socket_client("phaseit.net:80", $errno, $errstr, $timeout, STREAM_CLIENT_ASYNC_CONNECT/STREAM_CLIENT_CONNECT); if ($s) ( $sockets[$id++]=$s; $http_message=" GET /demonstration/delay?delay=" . $delay . " HTTP/1.0\r\nHost: phaseit.net\r\n\r\n"; fwrite($s, $http_message); ) else ( echo "Stream " . $id . " failed to open correctly."; ) $delay -= 3; ) while (count($sockets)) ( $read=$sockets; stream_select($read, $w=null, $e=null , $timeout); if (count($read)) ( /* stream_select normally shuffles $read, so we have to figure out which socket to read from. */ foreach ($read as $r) ( $id=array_search($ r, $sockets); $data=fread($r, $convenient_read_block); /* The socket can be read either because it has data to read OR because it is in the EOF state. */ if (strlen($data) = = 0) ( echo "Stream " . $id . " closes at " . date("h:i:s") . ".\n"; fclose($r); unset($sockets[$id]); ) else ( $result[$id] .= $data; ) ) ) else ( /* Thai maut means that *all* threads did not wait for a response. */ echo "Time-out!\n"; break; ) ) ?> |
If you run this program, the following information will be displayed:
Program starts at 02:38:50. Stream 4 closes at 02:38:53. Stream 3 closes at 02:38:56. Stream 2 closes at 02:38:59. Stream 1 closes at 02:39:02. Stream 0 closes at 02:39:05. |
It's important to understand what's going on here. At a high level, the first program makes several HTTP requests and retrieves the pages that the Web server passes to it. Although a real application would probably request several different Web servers (perhaps google.com, yahoo.com, ask.com, etc.), this example passes all requests to our corporate server at Phaseit.net just to reduce complexity. .
The requested Web pages return results after the variable delay shown below. If the program were to execute requests sequentially, it would take about 15+12+9+6+3 (45) seconds to complete. As shown in Listing 2, it actually completes in 15 seconds. Tripling productivity is a great result.
This is made possible by stream_select, a new feature in PHP V5. Requests are initiated in the usual way - by opening multiple stream_socket_clients and writing a GET to each of them, which corresponds to http://phaseit.net/demonstration/delay?delay=$DELAY . When you request this URL in a browser, you should see:
Although the specific implementation in Listing 3 is for UNIX®, almost all of the scenarios in this article work just as well for PHP installations on Windows® (especially after Windows 98) or UNIX. In particular, Listing 1 works on any operating system. Linux® and Mac OS X are variations of UNIX, and all of the code here will work on both systems.
Requests to the delay server are made in the following order:
delay=15 delay=12 delay= 9 delay= 6 delay= 3 |
The purpose of stream_select is to get results as quickly as possible. In this case, the order of the delays is the opposite of the order in which the requests were made. After 3 seconds, the first page is ready for reading. This part of the program is normal PHP code - in this case, with fread . Just like in another PHP program, reading could be done with fgets .
Processing continues in the same way. The program blocks in stream_select until the data is ready. The crucial thing is that it starts reading as soon as any connection has data, in any order. This is how the program implements multitasking or parallel processing of the results of several queries.
Note that there is no additional CPU load on the host machine. It's not unusual for network programs that fread this way to start using 100% of the CPU's power soon. This is not the case here, since stream_select has the desired properties and responds immediately as soon as any reading becomes possible, while still minimally occupies the CPU in idle mode between reads.
Things to know about stream_select()
Such event-based programming is not an elementary task. Although Listing 1 has been reduced to the most basic points, any coding based on callbacks or coordination (which is necessary in multitasking applications) will be less familiar than a simple procedural sequence. In this case, the biggest difficulty lies in the $read array. Note that this is a link; stream_select returns important information by changing the contents of $read . Just as pointers have a reputation for being a constant source of bugs in C, references seem to be the part of PHP that poses the most difficulty for programmers.
This query technique can be used from any number of external Web sites, making sure the program gets each result as quickly as possible without waiting for other queries. In fact, this technique works correctly with any TCP/IP connection, not just the Web (port 80), so in principle you can control LDAP data retrieval, SMTP transmission, SOAP requests, etc.
But that's not all. PHP V5 manages the various connections as "streams" rather than simple sockets. The PHP Client URL Library (CURL) supports HTTPS certificates, FTP outbound download, cookies, and more (CURL allows PHP applications to use various protocols to connect to servers). Because CURL exposes the stream interface, the connection is transparent from the program's point of view. The next section explains how stream_select multiplexes even local computations.
There are a few caveats to stream_select. This function is not documented, so it is not covered even in new PHP books. Several of the code examples available on the Web simply don't work or are not clear. The second and third arguments to stream_select , which control the write and exception channels corresponding to the read channels in Listing 1, should almost always be null. With few exceptions, choosing these channels is a mistake. If you do not have sufficient experience, use only well-described options.
Also, stream_select appears to be buggy, at least as of PHP V5.1.2. Most importantly, the return value of a function cannot be trusted. While I haven't debugged the implementation yet, my experience has shown that it's safe to test count($read) as in Listing 1, but that doesn't apply to the return value of stream_select itself, despite the official documentation.
PHP Local Concurrency
The example and the bulk of the discussion above focused on how to manage multiple remote resources at the same time and get results as they come, rather than waiting for each one to be processed in the order of the initial requests. This is undoubtedly an important application of PHP's parallelism. Sometimes real applications can be sped up by a factor of ten or more.
What if the deceleration happens closer? Is there a way to speed up getting results in PHP when processing locally? There are several. They are perhaps even less well known than the socket-oriented approach in Listing 1. There are several reasons for this, including:
- For the most part, PHP pages are fast enough. Better performance might be an advantage, but it's not enough to justify the investment in new code.
- Using PHP in Web pages can make partial code speedups unimportant. Redistributing computations in such a way as to get intermediate results faster does not matter when the only criterion is the speed of delivery of the Web page as a whole.
- Few local bottlenecks are controlled by PHP. Users may complain that retrieving account information takes 8 seconds, but this may be a limitation of processing the database or some other resources external to PHP. Even if you reduce the PHP processing time to zero, it will still take more than 7 seconds just for searching.
- Even fewer restrictions lend themselves to parallel processing. Suppose a particular page calculates a recommended price for a listed common stock, and the calculations are quite complex and take many seconds. The computation may be sequential in nature. There is no obvious way to allocate it for "collaboration".
- Few PHP programmers understand PHP's potential for parallel processing. When talking about the possibility of parallelization, most of the programmers I met simply quoted the phrase "PHP does not work with threads" and returned to their established model of computing.
Sometimes more can be achieved. Suppose a PHP page needs to calculate two stock prices, perhaps compare them, and the host machine being used is multiprocessor. In this case, we can nearly double the performance by assigning two separate, time-consuming computations to different processors.
In the world of PHP computing, such examples are rare. However, since I have not found an exact description anywhere else, I want to give an example of such an acceleration here.
array("pipe", "r"), 1 => array("pipe", "w"), 2 => array("file", $error_log, "w")); $cmd="sleep" . $delay. "; echo "Finished with delay of " . $delay . ""."; $handles[$id]=proc_open($cmd, $descriptorspec, $pipes); $streams[$id]=$pipes; $all_pipes[$id]=$pipes; $delay -= 2; ) while (count($streams)) ( $read=$streams; stream_select($read, $w=null, $e=null, $timeout); foreach ($read as $r) ( $id=array_search($ r, $streams); echo stream_get_contents($all_pipes[$id]); if (feof($r)) ( fclose($all_pipes[$id]); fclose($all_pipes[$id]); $return_value=proc_close ($handles[$id]); unset($streams[$id]); ) ) ) ?> |
This program will display the following information on the screen:
Program starts at 10:28:41. Finished with delay of 1. Finished with delay of 3. |
The meaning is that PHP launched two independent subprocesses, received data from the first, and then from the second, although the latter started earlier. If the host computer is multiprocessor and the operating system is properly configured, it takes care of assigning different subroutines to different processors. This is one way to take advantage of multiprocessing machines in PHP.
Summary
PHP supports multitasking. PHP doesn't support stream processing in the way that other programming languages like Java or C++ do, but the examples above have shown that PHP has more potential for speedup than many realize.
To-do lists are a great way to keep track of your daily tasks. In this tutorial, we will build our own to-do list using PHP, MySQL, and AJAX. This tutorial assumes that you have a basic understanding of HTML, PHP, MySQL, and JavaScript.
We will be using the following files throughout this tutorial. You can download them using the link below. Feel free to use an alternative structure, but remember to change your file paths from those in the example code.
Main Index File
The first thing we need to do is lay out the structure for our main index page ( index.php). This application will only have one page and we will use AJAX to add and delete to-do items. Open the index.php file and add the following code.
Note: For the sake of time, we will not cover styling in this tutorial. A CSS file has been included in the source files.
Connecting to the MySQL Database
We need to set up a MySQL database for storing our to-do items. The easiest way to do this is trough a server-side tool called phpMyAdmin . The tools comes pre-installed on most web hosts and is bundled with local development services such as WampServer and XAMPP. We will be setting up one table with the name of 'tasks' and the following columns in this order: 'id', 'task', 'date', 'time'. Be sure to set the id column to auto-increment (there should be a checkbox labeled ‘A_I’).
After creating the new table, we need to connect our project to the database. open connect.php and add the following code to the file. Be sure to substitute your database details for the 'username', 'password', and 'database_name' fields. Save the file when you are done.
Explaining the Code
PHP has a mysql_connect() function that creates a connection to the MySQL server. The server variable should remain set to 'localhost' unless your database is hosted on a different server than the project files. In that case, substitute this value for the MySQL server's IP address. Once the connection has been made, the mysql_select_db() function selects a specific database from the server.
Now that we have created our connect.php file, we need to add it to the main index file. Add the following code to index.php and save the change.
Adding a New To-Do Item
The next thing we want to do is create a way to add items to our to-do list. To do this, we will use a form and submit the results to the database. Add the following