├── 9781484224809.jpg
├── LICENSE.txt
├── README.md
├── appendix-A
├── p4-compile.sh
└── p7-compile-ext.sh
├── cli-sapi
├── p11-arguments.php
├── p15-myscript.php
├── p19-myscript.desktop
├── p20-ourstats.bat
├── p21-our_text_ed.vbs
└── p21-unity-myscript.desktop
├── contributing.md
├── devtools
└── p4-initialise.php
├── distribution
├── p2-syslog.php
├── p4-embed.php
└── p5-using-phar.php
├── interactions
├── p12-generator2.php
├── p13-display2.php
├── p22-tmpfs.sh
├── p4-semaphore.php
├── p7-generator.php
└── p8-display.php
├── performance
└── p5-profile.php
├── system-software
├── p15-inotify.php
├── p19-inotifywait.php
├── p4-daemon.php
└── p9-libevent.php
├── system
├── p10-list-printers.php
├── p11-write-registry.php
├── p12-signals.php
├── p15-timed-event.php
├── p19-pdf.php
├── p2-bigfile.php
├── p29-gpio.php
├── p4-bigfilelines.php
├── p6-caches.php
└── p9-read-registry.php
└── user-software
├── p10-std-stream.php
├── p13-notify-send.php
├── p14-zenity.php
├── p16-html.php
├── p2-snake.php
├── p21-myapp.php
└── p6-interface.php
/9781484224809.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/php-beyond-the-web/37552081130418473c6af816abb82301c5c90622/9781484224809.jpg
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/php-beyond-the-web/37552081130418473c6af816abb82301c5c90622/LICENSE.txt
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Apress Source Code
2 |
3 | This repository accompanies [*PHP Beyond the Web*](http://www.apress.com/9781484224809) by Rob Aley (Apress, 2017).
4 |
5 | 
6 |
7 | Download the files as a zip using the green button, or clone the repository to your machine using Git.
8 |
9 | ## Releases
10 |
11 | Release v1.0 corresponds to the code in the published book, without corrections or updates.
12 |
13 | ## Contributions
14 |
15 | See the file Contributing.md for more information on how you can contribute to this repository.
16 |
--------------------------------------------------------------------------------
/appendix-A/p4-compile.sh:
--------------------------------------------------------------------------------
1 | mkdir php5.4
2 | cd php5.4
3 | wget http://uk3.php.net/get/php-7.0.11.tar.gz/from/uk.php.net/mirror -o php-7.0.11.tar.gz
4 | tar zxvf php-7.0.11.tar.gz
5 | cd php-7.0.11
6 | ./configure
7 | make clean
8 | make
9 | sudo make install
10 |
--------------------------------------------------------------------------------
/appendix-A/p7-compile-ext.sh:
--------------------------------------------------------------------------------
1 | cd pcntl
2 | phpize
3 | ./configure
4 | make clean
5 | make
6 | sudo make install
7 |
--------------------------------------------------------------------------------
/cli-sapi/p11-arguments.php:
--------------------------------------------------------------------------------
1 | addHeader ( 'Content-Type' , "text/plain; charset=ISO-8859-1",
19 | EventHttpRequest::OUTPUT_HEADER );
20 |
21 | # Next we'll gather some information about the request, and format
22 | # it into a string to send back to the web browser.
23 |
24 | $replyText .= 'Command : ' . $req->getCommand() . "\n";
25 |
26 | $replyText .= 'Host : ' . $req->getHost() . "\n";
27 |
28 | $replyText .= 'Input Headers : ' .
29 | var_export($req->getInputHeaders(),true) . "\n";
30 |
31 | $replyText .= 'Output Headers : ' .
32 | var_export($req->getOutputHeaders(),true) . "\n";
33 |
34 | $replyText .= 'URI : ' . $req->getUri() . "\n";
35 |
36 | # To send a reply back, we create an "EventBuffer" containing the
37 | # reply contents, in our case the $replyText above
38 |
39 | $reply = new EventBuffer;
40 |
41 | $reply->add($replyText);
42 |
43 | # Finally we send our EventBuffer to the browser, with an HTTP
44 | # status of 200-OK to confirm everything happened correctly.
45 |
46 | $req->sendReply(200, "OK", $reply);
47 |
48 | };
49 |
50 | function closeServer($req) {
51 |
52 | # Our next function allows the visitor to shut down the server by
53 | # simply visiting a URL. We'll send them a message before we shut down
54 | # to let them know.
55 |
56 | $reply = new EventBuffer;
57 |
58 | $reply->add("Ok 1337 haxor, you've killed the server...");
59 |
60 | $req->sendReply(200, 'OK', $reply);
61 |
62 | # We then call the exit method of the event base, to exit the event
63 | # loop, which we'll look at towards the end of the program.
64 |
65 | global $base;
66 |
67 | $base->exit();
68 |
69 | };
70 |
71 | function notFound($req) {
72 |
73 | # This function handles the case where we can't find a resource
74 |
75 | $req->sendError(404, 'Does not appear to be here. Sorry.');
76 |
77 | };
78 |
79 | function cat($req) {
80 |
81 | # This function is one of the most important on the internet. It
82 | # returns a picture of a cat. You will need a cat picture named
83 | # cat.jpg in the same directory for this to work, but that shouldn't
84 | # be too difficult to arrange...
85 |
86 | # As we're returning a binary image file, we need to set the
87 | # appropriate mime-type output header.
88 |
89 | $req->addHeader ( 'Content-Type' , "image/jpeg" ,
90 | EventHttpRequest::OUTPUT_HEADER );
91 |
92 | # Get the contents of the image file ....
93 |
94 | $cat = file_get_contents('cat.jpg');
95 |
96 | # and add them to a new EventBuffer ...
97 |
98 | $reply = new EventBuffer;
99 |
100 | $reply->add($cat);
101 |
102 | # finally delivery the cat to an appreciative audience ....
103 |
104 | $req->sendReply(200, "OK", $reply);
105 |
106 | };
107 |
108 | function genericHandler($req) {
109 |
110 | # This function will handle any requests that the previous functions
111 | # haven't. We'll use the opportunity to serve up an HTML page with a
112 | # title and a picture of a cat. The tag will cause the browser
113 | # to make a second call, which will be routed to the cat() function
114 | # above to deliver the image file.
115 |
116 | $replyText = '
In the traditional PHP Way
27 |28 | An Important Link 29 | '); 32 | 33 | fwrite(STDOUT, "Finished HTML Generation\n"); # displayed in terminal 34 | 35 | # ob_get_contents() creates a string with everything buffered so far. 36 | 37 | $ourHtml = ob_get_contents(); 38 | 39 | # We can continue with buffering if we need to, or in this case we 40 | # end "ob_end_clean"ly. If we ob_end_flush() instead, then the contents of 41 | # the buffer would be pushed to php://output, which after ending the 42 | # buffering is STDOUT, which we don't want in this case. 43 | 44 | ob_end_clean(); 45 | 46 | # Now that we've ended buffering… 47 | 48 | echo ("This Text will go to our terminal via STDOUT\n"); 49 | 50 | # Finally, we want to save the buffered HTML to a file. Lets create 51 | # a unique temporary file name .... 52 | 53 | $filename = tempnam(sys_get_temp_dir(), 'my_report_').'.html'; 54 | 55 | # and write the HTML string to it. 56 | 57 | file_put_contents($filename, $ourHtml); 58 | 59 | # Finally, we want to open a web browser to view the HTML "report" we 60 | # just created. Here we use the helper command "see" (available on 61 | # most Debian based distros) to open the default viewer for the filetype 62 | # (HTML). The command "open" achieves the same thing on other platforms. 63 | # On Windows, you can ommit the helper command and just "execute" the 64 | # $filename (i.e. `$filename`) and Windows will open the default viewer 65 | # (browser) for that filetype. 66 | # 67 | # You can also specify a particular browser if you want, 68 | # e.g. `firefox $filename`. 69 | 70 | `see $filename`; 71 | -------------------------------------------------------------------------------- /user-software/p2-snake.php: -------------------------------------------------------------------------------- 1 | intval($cols/2), "y"=>intval($rows/2)]; 89 | 90 | # Now for our first element of flow control. We need to keep the program 91 | # running until the user provides input. The simplest way to do this is to 92 | # use a never-ending loop using while(1). "1" always evaluates to true, so 93 | # the while loop will never end. When we (or the user) are ready to end 94 | # the program, we can use the "break" construct to step out of the loop 95 | # and continue the remaining script after the end of the loop. 96 | 97 | while (1) { 98 | 99 | # Each time we go through the loop, we want to check if the user has 100 | # pressed enter while we were in the last loop. Remember that STDIN is 101 | # no longer blocking, so if there is no input the program continues 102 | # immediately. If there is input we use break to leave the while loop. 103 | 104 | if (fread(STDIN,1)) { break; }; 105 | 106 | # We will step the position of the cursor, stored in $p, by a random 107 | # amount in both the x and y axis. This makes our snake crawl! 108 | 109 | $p['x'] = $p['x'] + rand(-1,1); 110 | $p['y'] = $p['y'] + rand(-1,1); 111 | 112 | # We check that our snake won't step onto or over the frame, to keep 113 | # it in its box! 114 | 115 | if ($p['x'] > ($cols-1)) { $p['x'] = ($cols-1);}; 116 | if ($p['y'] > ($rows-1)) { $p['y'] = ($rows-1);}; 117 | if ($p['x'] < 2) { $p['x'] = 2;}; 118 | if ($p['y'] < 2) { $p['y'] = 2;}; 119 | 120 | # We want a pretty trail, so we need to pick random colours for the 121 | # foreground and background colour of our snake, that change at 122 | # each step. Colours in the terminal are set with yet more escape 123 | # codes, from a limited palette, specified by integers. 124 | 125 | $fg_color = rand(30,37); 126 | $bg_color = rand(40,47); 127 | 128 | # Once chosen, we set the colours by outputting the escape codes. This 129 | # doesn't immediately print anything, it just sets the colour of 130 | # whatever else follows. 131 | 132 | fwrite(STDOUT, ESC."[${fg_color}m"); # \033[$32m sets green foreground 133 | fwrite(STDOUT, ESC."[${bg_color}m"); # \033[$42m sets green background 134 | 135 | # Finally we output a segment of snake (another box drawing character) 136 | # at the new location. It will appear with the colours we just set, at 137 | # the location stored in $p 138 | 139 | fwrite(STDOUT, ESC."[${p['y']};${p['x']}f"."╬"); 140 | 141 | # Before we let the while loop start again, we need to do one more 142 | # very important thing. We need to give your processor a rest. 143 | # If we just continued our loop straight away, you would find your 144 | # processor being hammered, just for our relatively simple program. 145 | # Our snake would also consume the screen at super-speed! 146 | # usleep pauses execution of the program, so others can use the 147 | # processor or the processor can "rest". Every little bit helps the 148 | # responsiveness of your machine, so even if you need your program 149 | # to loop as fast as possible, consider even a small usleep if you can 150 | 151 | usleep(1000); 152 | }; 153 | 154 | # If this line of code has been reached, it means that we have 'break'd 155 | # from the while loop. 156 | 157 | # To be a good citizen of the terminal, we need to clean up the screen 158 | # before we exit. Otherwise, the cursor will remain on which-ever line 159 | # our snake left it, and the background/foreground colours will be 160 | # the last ones chosen for our snake segment. 161 | 162 | # The following escape code tells the terminal to use its default colours. 163 | 164 | fwrite(STDOUT, ESC."[0m"); 165 | 166 | # We then clear the screen and put the cursor at the top-left, as we 167 | # did earlier. 168 | 169 | fwrite(STDOUT, CLEAR.HOME); 170 | -------------------------------------------------------------------------------- /user-software/p21-myapp.php: -------------------------------------------------------------------------------- 1 | Destroy(); 18 | } 19 | 20 | # We'll add a function to display an "about" dialog to display some 21 | # information about the application 22 | 23 | function onAbout() 24 | { 25 | 26 | # "wxMessageDialog" is one of the many components or "widgets" 27 | # available in the toolkit. This saves you having to create a 28 | # new frame/window to display your message. 29 | 30 | $dlg = new wxMessageDialog( 31 | $this, 32 | "Welcome to wxPHP!!\nBased on wxWidgets 3.0.0\n\n". 33 | "This is a minimal wxPHP sample!", 34 | "About box...", 35 | wxICON_INFORMATION 36 | ); 37 | 38 | # Show the dialog box we create above. 39 | 40 | $dlg->ShowModal(); 41 | } 42 | 43 | # Add a constructor function. This function is run when we create our 44 | # application window by creating a new object from this class. 45 | 46 | function __construct() 47 | { 48 | 49 | # This calls the constructor function from the wxFrame class that 50 | # we have extended, creating a frame with the title 51 | # "Minimal wxPHP App" in the default position on screen, with 52 | # the initial size of 350 x 260 pixels. Note that this frame is 53 | # not visible by default, it's just created in memory at the 54 | # moment. This means that we can add things to it and fully 55 | # prepare it before we show it to the user, rather than the 56 | # user seeing a blank window that then suddenly fills with 57 | # buttons etc. 58 | 59 | parent::__construct(null, null, "Minimal wxPHP App", 60 | wxDefaultPosition, new wxSize(350, 260)); 61 | 62 | # We're going to add menus to our window with various options, 63 | # which means first adding a menu bar into which we put the menus. 64 | 65 | $mb = new wxMenuBar(); 66 | 67 | # Now we add the menus. First a "File" menu with a "Quit" option 68 | 69 | $mn = new wxMenu(); 70 | $mn->Append(2, "E&xit", "Quit this program"); 71 | $mb->Append($mn, "&File"); 72 | 73 | # And now a "Help" menu with an "About" option. 74 | 75 | $mn = new wxMenu(); 76 | $mn->AppendCheckItem(4, "&About...", "Show about dialog"); 77 | $mb->Append($mn, "&Help"); 78 | 79 | # Note the menu and options above all have "&"" symbols in. This 80 | # comes before the letter that should be used for keyboard 81 | # shortcuts. Using a widget toolkit like this means that you don't 82 | # have to write your own code for managing things like keyboard 83 | # shortcuts, saving you time and effort and creating a consistent 84 | # experience for your users. 85 | 86 | # Finally add the menu bar to the frame. 87 | 88 | $this->SetMenuBar($mb); 89 | 90 | # Lets add a source-code editing box to the frame, which is 91 | # another one of the available widgets in the toolkit and has 92 | # functionality like syntax highlighting, smart indentation etc. 93 | 94 | $scite = new wxStyledTextCtrl($this); 95 | 96 | # The final widget we're going to add is a status bar at the 97 | # bottom of the window. 98 | 99 | $sbar = $this->CreateStatusBar(2); 100 | $sbar->SetStatusText("Welcome to wxPHP..."); 101 | 102 | # At the start of this class we defined a couple of functions, one 103 | # to show an about box, and one to quit the app. On their own 104 | # they won't do anything, we need to connect them to the menu 105 | # options we created earlier. More specifically, to the 106 | # "wxEVT_COMMAND_MENU_SELECTED" event which is called when the 107 | # user selects something from the menu. 108 | 109 | $this->Connect(2, wxEVT_COMMAND_MENU_SELECTED, array($this,"onQuit")); 110 | 111 | $this->Connect(4, wxEVT_COMMAND_MENU_SELECTED, array($this,"onAbout")); 112 | 113 | } 114 | } 115 | 116 | # We've now designed our frame and populated it with widgets and functions 117 | # but at this stage in the code it doesn't yet exist. We need to create 118 | # a new object using our class, which will bring it to life and call 119 | # the constructor function above. 120 | 121 | $mf = new mainFrame(); 122 | 123 | # The frame now exists, it is populated with widgets and the functions 124 | # are all hooked up to the events. However it is hidden, so we need 125 | # to make it visible. 126 | 127 | $mf->Show(); 128 | 129 | # At this point, we need to let wxWidgets take over and run the show. 130 | # Calling wxEntry lets wxWidgets manage the application, wait for and 131 | # react to events and call the functions that we've previously specified. 132 | # As you can see, we need to have specified all of our applications code 133 | # before we get to this point. 134 | 135 | wxEntry(); 136 | 137 | # If we reach this point, it means that our application has quit (either 138 | # the user has closed it or something in our code has closed it), and 139 | # we can either do any tidy-up necessary or just quit. 140 | -------------------------------------------------------------------------------- /user-software/p6-interface.php: -------------------------------------------------------------------------------- 1 | "); 51 | 52 | # We need to manually add commands to the history. This is used for 53 | # the command history that the user accesses with the up/down cursor 54 | # keys. We could choose to ignore commands (mis-typed ones or 55 | # intermediate input, for example) if we want, although we'll add 56 | # everything our users enter in this example. 57 | 58 | readline_add_history($line); 59 | 60 | # If we want to programmatically retrieve the history, we can use a 61 | # function called readline_list_history(). However, this is only 62 | # available if PHP has been compiled using libreadline. In most cases, 63 | # modern distributions compile it using the compatible libedit library 64 | # for licensing and other reasons. So we will keep a parallel copy of 65 | # the history in an array for programatic access. 66 | 67 | $history[] = $line; 68 | 69 | # Now we decide what to do with the users input. In real life, we may 70 | # want to trim(), strtolower() and otherwise filter the input first. 71 | 72 | switch ($line) { 73 | 74 | case "kill": 75 | 76 | echo "You don't want to do that.\n"; 77 | 78 | break; 79 | 80 | case "destroy": 81 | 82 | echo "That really isn't a good idea.\n"; 83 | 84 | break; 85 | 86 | case "obliterate": 87 | 88 | echo "Well, if we really must.\n"; 89 | 90 | break; 91 | 92 | case "history": 93 | 94 | # We will use the parallel copy of the command history that we 95 | # created earlier to display the command history. 96 | 97 | $counter = 0; 98 | 99 | foreach($history as $command) { 100 | 101 | $counter++; 102 | 103 | echo("$counter: $command\n"); 104 | 105 | }; 106 | 107 | break; 108 | 109 | case "byebye": 110 | 111 | # If it's time to leave, we want to break from both the switch 112 | # statement and the while loop, so we break with a level of 2. 113 | 114 | break 2; 115 | 116 | default : 117 | 118 | # Always remember to give feedback in the case of user error. 119 | 120 | echo("Sorry, command ".$line." was not recognised.\n"); 121 | } 122 | 123 | }; 124 | 125 | # If we reached here, outside of the while(1) loop, the user typed byebye. 126 | 127 | echo("Bye bye, come again soon!\n"); 128 | --------------------------------------------------------------------------------