Tuesday, July 14, 2009

Advanced PHP for Web Professionals By Christopher Cosentino Chapter 12

Introduction to PHPGTK
PHPGTK is an extension to PHP that allows you to create graphical user interface (GUI) applications. Instead of running in a browser, your PHP application runs in its own application window. These applications are client-side only. They do not reside on the Web server. The files instead reside on the user's hard drive. For users to use the PHPGTK application, they must have the proper version of PHP (with the GTK+ extension) installed on their system.

GTK+ was originally designed for the open-source image editing program called the GIMP (GNU Image Manipulation Program). GTK stands for the GIMP Tool Kit. Later, the Gnome team decided to use GTK+ to create their desktop environment for Linux. GTK+ has been ported to Windows, Linux, and BeOS, and thus makes for a good cross-platform GUI library.

PHPGTK uses GTK+ to draw the "widgets" required in any GUI application. Widgets are things like scroll bars, text input fields, and buttons, among other things. When you start almost any Windows application, such as a Web browser, you are looking at a collection of widgets.

Widgets need to be contained in some type of framework to be useful and logical. You can't just have a bunch of buttons and text fields scattered randomly about the screen. To solve this problem, we use a special kind of widget called a container. A container is another structure that organizes the widgets however you think it best for your application. For example, the menu bar at the top of most applications is a container.

Widgets have many different properties that control how they look and act. Each type of widget has its own unique set of properties, in addition to properties that are common to other widgets.

Widgets send signals to your program when they are activated. An example of widget activation is when a user clicks on a button. Once a widget sends a signal, you generally respond to that signal with a callback. A callback is basically just a function. Some signals end up in callbacks that are automatically handled by GTK (default handlers). Other signals end up executing one of your functions (user-defined handlers). The user-defined functions are written in PHP.

As of the writing of this document, the current version of PHPGTK was 0.5.1, released on April 26, 2002. While still in its early stages, PHPGTK 0.5.1 is a vast improvement over the original 0.1 release.

PHPGTK is very complex. It takes basically two complete languages and puts them together. This lone chapter cannot hope to explain in detail the many methods and classes that are available, but I wish to provide a general overview of PHPGTK insofar as this space allows. Check the PHPGTK Web site at http://gtk.php.net for a wealth of information!

Installing PHPGTK
Before you can start using PHPGTK, you need to download the appropriate files. The PHPGTK team has set up a nice Web site at http://gtk.php.net. The PHPGTK Web site has downloads and documentation for the GTK extension.

Before You Install
PHPGTK still has not reached the 1.0 version, and as such I wouldn't recommend that you use this version of PHP on your production Web server. In fact, there really isn't a reason that you'd want to install PHPGTK on your production Web server. It is a client-side application!

PHPGTK is a developers' toy at the moment, and anything is subject to change, at least before PHPGTK reaches version 1.0. Have some fun with it, try it out, but don't base your company's next big product on PHPGTK 0.5.0.

Installing on Windows
Installing PHPGTK on a Windows machine is fairly straightforward and similar to installing the normal version of PHP. Download the Windows binary file from the PHPGTK Web site at http://gtk.php.net.

Unzip the file using a zip utility such as WinZip. Extract the files to your C: drive.

The following folders are created when you unzip the file:

php4— Contains the PHP executable, as well as some GTK library files.

test— Contains some sample *.php files that use the GTK widget set.

If you are using Windows 98 or Windows ME, then you will notice that folders called "winnt" and "winnt/system32" have been created. You should copy the contents of those folders into your C:\windows directory. Note that you may have to set your system files to be viewable so that you can see the necessary DLL files to copy them over to C:\windows.

Additionally, you should see a new php.ini file. Copy this to your C:\Windows or C:\WINNT directory. Be sure to first back up your existing php.ini file.

To test out the installation, type the following from a command prompt:

c:\php4\php.exe -q c:\test\gtk.php

See Figure 12-1 for a screen shot of the gtk.php file in action.

Figure 12-1. gtk.php in Linux (Gnome) and Windows 2000

Installing on Linux
Installing PHPGTK on Linux is easier than installing the normal PHP; you don't have to worry about compiling with Apache. You can compile GTK functionality into an existing standalone version of PHP, but for our purposes we'll start from scratch and make a brand new PHP executable that has GTK functionality built in. Before you begin:

Download the source file for PHP from the download page at www.php.net.

Download the source file PHPGTK from the download page of http://gtk.php.net.

Once you have the necessary file, unzip and untar the regular PHP source file:

tar -zxvf php-4.x.x.tar.gz

This creates a new directory named php-4.x.x, where the "x" denotes the exact version number of PHP that you downloaded.

Compile PHP using the minimum options. We just want to create a standalone executable. If you want to add additional functionality, you can recompile later. For now, you just want to make sure you can create a working version of PHPGTK. Change directory into your newly created PHP source directory. Compile by typing:

./configure

That's all there is to it. This automatically creates an executable that has built-in MySQL support as well.

Once you have the php binary file, you must copy it to /usr/local/bin. The PHPGTK installation will be looking for it in that location. You need to be root to do this.

cp php /usr/local/bin

Now, it's time to build the GTK extension onto your PHP executable. Go back to where you downloaded the PHPGTK source file and extract it:

tar -zxvf php-gtk-0.5.0.tar.gz

This creates a new directory named php-gtk-0.5.0. Change directory into that directory and compile the source file. You will need to be root to perform the final step, make install. To compile PHPGTK, type the following (a lot of text will print to the screen after you type each command):

./compile

make

make install

You can test your installation by going into the test directory and running a few of the scripts. X-Windows will need to be running!

cd test
php -q gtk.php

A window should pop up showing various GTK widget buttons. Click the different widgets to get a brief idea of what they do.

Figure 12-1 shows the gtk.php file as it appears in Linux (using the Gnome desktop) on the left and in Windows 2000 on the right.

You can also try running the other *.php files in the test directory. Use the -q flag to suppress printing HTTP header information to the screen (the php "quiet" option).

Creating Basic GTK Objects
The GTK+ extension is an object oriented programming (OOP) extension to PHP. You need to use OOP syntax and structures to use the GTK+ library. If you haven't already done so, you may want to go all the way back to Chapter 1 and review the material about OOP in PHP.

Creating Your First PHPGTK Window
Before you can create any PHPGTK applications, you must tell PHP which GTK library you want to use. Since GTK runs on Windows and many flavors of UNIX, that leaves us with two types of libraries. Windows uses dynamic link libraries, also called DLLs. Most *nix based operating systems use .so libraries. Since you want your application to be able to be used on both types of operating systems without modification, you must provide a dynamic method of loading the libraries. The standard method of doing this is:

if (!class_exists('gtk')) {
if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN')
dl('php_gtk.dll');
else
dl('php_gtk.so');
}

Side Note
If you intend for your script to run on platforms other than Linux or Windows (if support for these other platforms is added in later versions of PHPGTK), then you must ensure that the proper PHPGTK library is loaded using the same manner as above.

The core part of any PHPGTK application is the main window. Each application you create should have a main window that acts as a container into which you place your other widgets.

The basic window class in PHPGTK is GtkWindow(). You create a new window object like this:

$window = &new GtkWindow();

Now that you have a window, you must provide for a way to destroy that window. In most operating systems, a user can destroy a window by clicking the "X" in the upper right corner of the window (some Linux desktops provide a different control).

When you click the "X" in a PHPGTK application, two signals are sent to the application. These signals are delete_event and destroy. For now we'll just concentrate on the destroy signal.

Signals are generally user input, and callbacks are functions that you create to do something in response to the user input. However, you need to connect the signal to the callback. To do this, you use the connect() method. To connect the destroy signal to our destroy callback:

$window->connect('destroy','destroy');

The first argument is the name of the signal that is sent by PHPGTK. The second argument is the name of the function (callback) that you want to call in response to the signal. To keep things simple, we'll name the function (callback) 'destroy'.

function destroy() {
Gtk::main_quit();
}

The Gtk::main_quit(); is the PHPGTK function that kills the application.

Now we have created a window and provided a means for the user to get rid of the window. But we still can't run the application. PHPGTK requires two more things to be done. First, we need to show the window. You show a window by calling the show_all() method:

$window->show_all();

Finally, you need to start the event sequence (polling events?) by calling the special PHPGTK function main():

Gtk::main();

Side Note
You must begin your scripts with the full "<?php" tag when using PHPGTK. Using the shorthand "<?" may cause PHPGTK to just echo the entire script to the screen instead of creating a GTK window.

When we put it all together, you get Script 12-1, basic_window.php.

Script 12-1 basic_window.php
1. <?php
2. if (!class_exists('gtk')) {
3. if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN')
4. dl('php_gtk.dll');
5. else
6. dl('php_gtk.so');
7. }
8. function destroy(){
9. Gtk::main_quit();
10. }
11. $window = &new GtkWindow();
12. $window->connect('destroy', 'destroy');
13. $window->show_all();
14. Gtk::main();
15. ?>

Run the script from the command line (remember, you need to add the full path to the PHP executable if it is not in the current directory):

php -q basic_window.php

The result should look similar to Figure 12-2. You can close the window by clicking the "X" in the upper right corner.

Figure 12-2. basic_window.php

Script 12-1. basic_window.php Line-by-Line Explanation LINE
DESCRIPTION

2
If the GTK class has not been defined, then execute lines 3–7. If the GTK class has been defined, then the script needs to do nothing.

3
Check the first three characters of the PHP_OS environment variable.

4
If it is WIN, then the system is running Windows. Load the PHPGTK library for Windows.

5–7
If the PHP_OS environment variable is not WIN, then assume that PHP is running on a Linux system and load the Linux PHPGTK library.

8–10
Define a function, destroy(), that stops the script when called.

9
Execute the Gtk::main_quit() method to stop the script and close the GTK window.

10
End the function declaration.

11
Create a new window object called $window.

12
Connect the destroy method of the window to the destroy() function that you defined earlier. The destroy method is called when the user clicks the "X" on the top right of the window.

13
Issue the show_all() function call to the $window object so that everything within the object is displayed.

14
Call the Gtk::main() method to run the script.

Adding a GTK Button
The simplest and most basic example in all of programming is the Hello World example. The goal of the example, if you didn't know, is to get the program to print out the words "Hello, World!" We are going to enhance our Hello World program slightly. Instead of merely printing out "Hello World," let's add that text to a button. When the button is clicked, we'll close our application. Try out this example, then look at the brief line-by-line explanation for details. Figure 12-3 shows the output of the script in Linux and in Windows.

Script 12-2 hello.php
1. <?php
2. if (!class_exists('gtk')) {
3. if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN')
4. dl('php_gtk.dll');
5. else
6. dl('php_gtk.so');
7. }
8. function destroy() {
9. Gtk::main_quit();
10. }
11. function hello(){
12. global $window;
13. print "Hello World!\n";
14. $window->destroy();
15. }
16. $window = &new GtkWindow();
17. $window->connect('destroy', 'destroy');
18. $button = &new GtkButton('Hello World!');
19. $button->connect('clicked', 'hello');
20. $window->add($button);
21. $window->show_all();
22. Gtk::main();
23. ? >

Figure 12-3. hello.php in Linux (Gnome) and Windows

Script 12-2. hello.php Line-by-Line Explanation LINE
DESCRIPTION

2
If the GTK class has not been defined, then execute lines 3–7. If the GTK class has been defined, then the script needs to do nothing.

3
Check the first three characters of the PHP_OS environment variable.

4
If it is WIN, then the system is running Windows. Load the PHPGTK library for Windows.

5–7
If the PHP_OS environment variable is not WIN, then assume that PHP is running on a Linux system and load the Linux PHPGTK library.

8–10
Define a function, destroy(), that stops the script when called.

9
Execute the Gtk::main_quit() method to stop the script and close the GTK window.

10
End the function declaration.

11–14
Define a function, hello(), that prints the text "Hello World!"

12
Allow the $window object to be accessed by this function.

13
Print the text "Hello World!" to STDOUT (the same command line from which you executed the script).

14
Use the destroy() method on the $window object to close the window.

15
End the function declaration.

16
Create a new window object called $window.

17
Connect the 'destroy' method of the window to the destroy() function that you defined earlier. The 'destroy' method is called when the user clicks the "X" on the top right of the window.

18
Create a new button object called $button.

19
Connect the 'clicked' method of the button to the hello() function.

20
Add the button to the window using the add() method.

21
Issue the show_all() function call to the $window object so that everything within the object is displayed.

22
Call the Gtk::main() method to run the script.

Modifying Basic Widget Appearance
The syntax for creating buttons and windows looks very similar. That is because they are both classes of a GTK widget. Each object (buttons, windows, etc.) has certain methods available to them—for example, the connect() method.

If you run the hello.php script, you will notice that the window size is pretty small—in fact, it is only as big as the button inside it. That's because PHP shrinks the window to the smallest size possible when creating it. We can modify the default appearance of the GtkWindow widget by using some methods. For example, if you wanted to set a default size for the window, you could use the set_default_size($width, $height)method:

$window->set_default_size(200,200);

This would create a window that is 200 pixels by 200 pixels. You can also set a window title:

$window->set_title("My PHPGTK APP");

Figure 12-4 shows a window modified by the set_default _size() and set_title() methods.

Figure 12-4. Window modified with property methods (Linux and Windows)

There are many methods available that can affect the appearance and behavior of GTK widgets. See the documentation on http://gtk.php.net for details on these methods.

Text Entry
A desktop application wouldn't be too useful if you couldn't insert data into it. GTK provides a text entry widget that allows you to input a line of text to your application. To create a text entry field:

$text1 = &new GtkEntry();

A text entry field isn't really useful unless you have some way to label it. That's where the GtkLabel comes in handy:

$label1 = &new GtkLabel("A Text Entry Field:");

Now that we have our new text entry field and a label, we need to put it into our window. There's a slight problem, though. You just can't add() multiple widgets into the top-level window. Instead, you place a box into the window, and add your subobjects into that box.

hbox and vbox
There are two types of boxes that you can use to hold your widgets in place within the main window. They are the hbox (horizontal) and the vbox (vertical). As their names imply, the hbox allows you to place objects into it so that the objects are aligned horizontally, and the vbox allows you to place objects into it so that the objects are aligned vertically. Since we want to align our text entry field and label horizontally (like normal applications do), we'll create an hbox and add it to our window, then pack the label and text entry field into the box:

$box = &new GtkHBox();
$window->add($box);

The hbox and vbox widgets are special containers into which you can add multiple widgets. To add them, you need to pack the widgets into the box:

$box->pack_start($label1, false, false, 0);
$box->pack_start($text1, false, false, 0);

pack_start
The pack_start method allows you to add the widgets into the box. If you are packing widgets into vbox, then pack_start adds the widgets from the top of the box. Each time you pack another widget into the box, the preceding widget is moved down and the newly added widget is at the top of the vbox. If you are packing widgets into an hbox, then pack_start adds the widgets into the box from the left. Each time you pack a new widget into the box, it is placed to the right of the preceding widget.

The pack_start() method takes four arguments:

The object you are packing.

Whether or not to expand the object if the box is resized (true or false).

Whether or not the object should fill the space which is available to it (true or false).

The amount of padding to use around the object (an integer).

The default arguments used, if none are specified, are true, true, 0. These mean to expand and fill and use no padding.

Let's look at a script the uses the label and text entry field. See Script 12-3, text_entry.php, below. See Figure 12-5 for the example output.

Script 12-3 text_entry.php
1. <?php
2. if (!class_exists('gtk')) {
3. if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN')
4. dl('php_gtk.dll');
5. else
6. dl('php_gtk.so');
7. }
8. function destroy(){
9. Gtk::main_quit();
10. }
11. $window = &new GtkWindow();
12. $window->connect('destroy', 'destroy');
13. $text1 = &new GtkEntry();
14. $label1 = &new GtkLabel("A Text Entry Field");
15. $box = &new GtkHBox();
16. $window->add($box);
17. $box->pack_start($label1, false, false, 0);
18. $box->pack_start($text1, false, false, 0);
19. $window->show_all();
20. Gtk::main();
21. ?>

Figure 12-5. text_entry.php

Script 12-3. text_entry.php Line-by-Line Explanation LINE
DESCRIPTION

2
If the GTK class has not been defined, then execute lines 3–7. If the GTK class has been defined, then the script needs to do nothing.

3
Check the first three characters of the PHP_OS environment variable.

4
If it is WIN, then the system is running Windows. Load the PHPGTK library for Windows.

5–7
If the PHP_OS environment variable is not WIN, then assume that PHP is running on a Linux system and load the Linux PHPGTK library.

8–10
Define a function, destroy(), that stops the script when called.

9
Execute the Gtk::main_quit() method to stop the script and close the GTK window.

10
End the function declaration.

11
Create a new window object called $window.

12
Connect the 'destroy' method of the window to the destroy() function that you defined earlier. The 'destroy' method is called when the user clicks the "X" on the top right of the window.

13
Create a new text-entry object called $text1.

14
Create a new label object called $label1 containing the text "A Text Entry Field".

15
Create a new horizontal box object called $box.

16
Add the box to the window using the add() method.

17
Pack the label object into the box.

18
Pack the text-entry object into the box.

19
Issue the show_all() function call to the $window object so that everything within the object is displayed.

20
Call the Gtk::main() method to run the script.

Putting It All Together
So now you know how to make a label, a button (with a label in it), and a text entry field. With these three tools, you can begin to build an application!

First, we need to know how to get the text the user enters in the text entry widget. The GtkTextEntry widget has a method that meets our needs:

$input = $text1->get_text();

You can assign the user-entered data using the get_text() method on the $text1 object to a variable (for example $input), then do whatever you want with that text. The following script puts it all together and provides a short example of a function to handle the user-entered text. See Figure 12-6 for example output.

Script 12-4 text_submit.php
1. <?php
2. if (!class_exists('gtk')) {
3. if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN')
4. dl('php_gtk.dll');
5. else
6. dl('php_gtk.so');
7. }
8. function destroy(){
9. Gtk::main_quit();
10. }
11. function submit(){
12. global $text1;
13. $input = $text1->get_text();
14. echo $input . "\n";
15. $text1->set_text('');
16. }
17. $window = &new GtkWindow();
18. $window->connect('destroy', 'destroy');
19. $window->set_border_width(5);
20. $text1 = &new GtkEntry();
21. $label1 = &new GtkLabel("A Text Entry Field");
22. $button1 = &new GtkButton('Submit Text!');
23. $button1->connect('clicked', 'submit');
24. $box = &new GtkHBox();
25. $window->add($box);
26. $box->pack_start($label1, false, false, 0);
27. $box->pack_start($text1, false, false, 0);
28. $box->pack_start($button1, false, false, 0);
29. $window->show_all();
30. Gtk::main();
31. ?>

Figure 12-6. text_submit.php

Script 12-4. text_submit.php Line-by-Line Explanation LINE
DESCRIPTION

2
If the GTK class has not been defined, then execute lines 3–7. If the GTK class has been defined, then the script needs to do nothing.

3
Check the first three characters of the PHP_OS environment variable.

4
If it is WIN, then the system is running Windows. Load the PHPGTK library for Windows.

5–7
If the PHP_OS environment variable is not WIN, then assume that PHP is running on a Linux system and load the Linux PHPGTK library.

8–10
Define a function, destroy(), that stops the script when called.

9
Execute the Gtk::main_quit() method to stop the script and close the GTK window.

10
End the function declaration.

11–16
Define a function, submit(), that echoes the user-entered text to STDOUT.

12
Allow the variable $text1 to be accessed by this function.

13
Assign the user-entered text to the $input variable by calling the get_text() method of the $text1 text object.

14
Echo the user-entered text to STDOUT along with a newline character

15
Clear the user-entered text from the text input by calling the set_text() method of the $text1 text object, assigning the new text to be blank ('').

16
End the function declaration.

17
Create a new window object called $window.

18
Connect the 'destroy' method of the window to the destroy() function that you defined earlier. The 'destroy' method is called when the user clicks the "X" on the top right of the window.

19
Set a five-pixel border around the window using the set_border_width method of the window object.

20
Create a new text-entry object called $text1.

21
Create a new label object called $label1 containing the text "A Text Entry Field".

22
Create a new button object called $button.

23
Connect the 'clicked' method of the button to the hello() function.

24
Create a new horizontal box object called $box.

25
Add the box to the window using the add() method.

26
Pack the label object into the box.

27
Pack the text-entry object into the box.

28
Pack the button object into the box.

29
Issue the show_all() function call to the $window object so that everything within the object is displayed.

30
Call the Gtk::main() method to run the script.

Dialog Boxes
Most GUI applications have the ability to display small windows notifying the user that something is wrong or to confirm that the user wants to take the desired action. For example, a dialog box appears asking "Are you sure…" in most word processing applications if you try to close the application without first saving the document on which you are working. PHPGTK also provides an easy way to create simple dialog boxes using the GtkDialog class.

The GtkDialog class is simply a window that contains a vbox, a separator, and an "action area." You place your text in the vbox and place your buttons in the "action area."

This next script shows an example of how to use a GtkDialog box to confirm that a user wishes to quit out of the application. When a user clicks the "Quit" button, or the "X" in the upper right corner of the main window, a dialog box is displayed, asking the users if they are sure they want to quit. If the user clicks "OK" in the dialog box, then the application exits. If the user clicks "Cancel" or the "X" in the upper right corner of the dialog box, then the dialog box closes, but the application remains open. See Figure 12-7 for example output.

Script 12-5 dialog.php
1. <?php
2. if (!class_exists('gtk')) {
3. if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN')
4. dl('php_gtk.dll');
5. else
6. dl('php_gtk.so');
7. }
8. function destroy() {
9. Gtk::main_quit();
10. }
11. function close_dialog($button, $dialog){
12. $dialog->destroy();
13. }
14. function delete_event(){
15. confirm();
16. return true;
17. }
18. function confirm(){
19. global $window;
20. $dialog = &new GtkDialog;
21. $dialog->set_title("Are You Sure?");
22. $dialog->set_default_size('100','100');
23. $dialog->set_modal(TRUE);
24. $dialog->set_transient_for($window);
25. $dialog->set_policy(0,0,0);
26. $label = &new GtkLabel("Are You Sure You Want To Quit?");
27. $button_yes = &new GtkButton('OK');
28. $button_yes->connect('clicked', 'destroy');
29. $button_no = &new GtkButton('Cancel');
30. $button_no->connect('clicked', 'close_dialog', $dialog);
31. $vbox1 = $dialog->vbox;
32. $vbox2 = $dialog->action_area;
33. $vbox1->pack_start($label);
34. $vbox2->pack_start($button_yes);
35. $vbox2->pack_start($button_no);
36. $dialog->show_all();
37. }
38. $window = &new GtkWindow();
39. $window->connect('delete_event', 'delete_event');
40. $button = &new GtkButton('Quit');
41. $button->connect('clicked', 'confirm');
42. $window->add($button);
43. $window->show_all();
44. Gtk::main();
45. ?>

Figure 12-7. dialog.php—initial window and confirmation dialog box

Script 12-5. dialog.php Line-by-Line Explanation LINE
DESCRIPTION

2
If the GTK class has not been defined, then execute lines 3–7. If the GTK class has been defined, then the script needs to do nothing.

3
Check the first three characters of the PHP_OS environment variable.

4
If it is WIN, then the system is running Windows. Load the PHPGTK library for Windows.

5–7
If the PHP_OS environment variable is not WIN, then assume that PHP is running on a Linux system and load the Linux PHPGTK library.

8–10
Define a function, destroy(), that stops the script when called.

9
Execute the Gtk::main_quit() method to stop the script and close the GTK window.

10
End the function declaration.

11–13
Define a function, close_dialog(), that closes a dialog box. This function takes two arguments: $button and $dialog. See the description for line 30 for a description of the arguments.

12
Call the destroy() method of the $dialog object to close the dialog window.

13
End the function declaration.

14–17
Define a function, delete_event(), that catches when a user clicks on the "X" in the upper-right corner of the main application window and runs the confirm function(). The delete_event() is a special method that is run whenever a user clicks the "X" in the upper-right corner of the application window. "delete_event" is a valid connection point for a window, similar to the destroy connection point. If you do not use a delete_event connection point, then the window is automatically destroyed.

15
Execute the confirm() function to make certain the user wishes to exit the application.

16
Return true. If you return false (which is the default behavior of the delete_event when you don't assign a connection to it), then the window is destroyed.

17
End the function declaration.

18–37
Define a function, confirm(), to confirm that the user wishes to quit the application.

19
Allow the $window object to be used by this function.

20
Create a new dialog object called $dialog.

21
Set the title for the dialog object.

22
Set the default size of the dialog window to be 100 x 100 pixels.

23
Set the dialog window as a modal window. This means that the main application window cannot be accessed while this window exists.

24
Set the dialog window as a transient of the main window. A transient window does not cause an extra taskbar item to be created in the OS for the window. This is currently broken on Windows but works under Linux.

25
Set the resize policy for the window. The resize() method takes three boolean (true or false/0 or 1) arguments:

allow_shrink— Allow the window to be smaller than its children (this should always be set to false).

allow_grow— Allow the window to be made greater than its original size.

auto_shrink— Allows the window to override its default size settings to shrink to the size of any child windows.

26
Create a new label object called $label.

27
Create a new button object called $button_yes. This is used as the "OK" button in the dialog box.

28
Use the connect() method to cause the destroy() function to be called when this button is clicked.

29
Create a new button called $button_no. This is used as the "Cancel" button in the dialog box.

30
Use the connect() method to cause the close_dialog() function to be called. Note that the connect method has an extra argument tagged on at the end. Normally, the connect() method has two arguments: the action (such as clicked) and the function that is called (such as close_dialog). You can add a third argument, which is an additional variable that is sent to the function. In this case, we are sending the dialog window object $dialog. Since we are sending two arguments, and the connected function usually takes only one by default (which is the object that is making the connection), you must define the default object ($button) and the additional object ($dialog) in the function for which you are creating the connection, in this case, close_dialog().

31
Since the GtkDialog object has built-in "boxes" for content, you need to assign a variable name for that object. Here you assign a variable name to the GtkDialog's vbox.

32
Assign a variable name to the GtkDialog's action_area.

33
Pack the label object into the vbox.

34–35
Pack the OK and Cancel buttons in the GtkDialog's action_area.

36
Show the contents of the dialog box.

37
End the function declaration.

38
Create a new window object called $window.

39
Connect the 'delete_event' method of the window to the delete_event() function that you defined earlier. The 'delete_event' method is called when the user clicks the "X" button in the upper right corner of the application. In the previous examples, we left this method out since we wanted to directly destroy the window.

40
Create a new button object called $button.

41
Connect the 'clicked' method of the button to the confirm function.

42
Add the button to the window using the add() method.

43
Issue the show_all() function call to the $window object so that everything within the object is displayed.

44
Call the Gtk::main() method to run the script.
A Simple PHPGTK Application
This next application uses GTK widgets to create a small application that encodes passwords. You enter a username and password into their respective fields, then click the "Generate…" button to create an encrypted username and password combination that can be used in some of the previous scripts in this book. The username and password are displayed in a text box in the middle of the application. When you have created as many passwords as needed, you can click the "Write To File" button to write the data to a text file. See Figure 12-8 for example output.

Script 12-6 password_gen.php
1. <?php
2. if (!class_exists('gtk')) {
3. if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN')
4. dl('php_gtk.dll');
5. else
6. dl('php_gtk.so');
7. }
8. function destroy(){
9. Gtk::main_quit();
10. }
11. function generate(){
12. global $user_in, $pass_in, $output;
13. $text = $user_in->get_text() . ":" . encoded($pass_in->get_text()) . "\n";
14. $output->insert(null, null, null, $text);
15. $user_in->set_text('');
16. $pass_in->set_text('');
17. }
18. function encoded($text) {
19. return md5($text);
20. }
21. function write(){
22. global $output;
23. $text = $output->get_chars(0,-1);
24. $file = fopen("pass.txt", "w") or die("CANNOT OPEN FILE");
25. fwrite($file, $text);
26. fclose($file);
27. $output->delete_text(0,-1);
28. $complete = "Passwords written to file!\n";
29. $output->insert(null, null, null, $complete);
30. }
31. $window = &new GtkWindow();
32. $window->set_default_size(300, 300);
33. $window->connect('destroy', 'destroy');
34. $user_label = &new GtkLabel("Username: ");
35. $user_in = &new GtkEntry();
36. $user_box = &new GtkHBox();
37. $user_box->pack_start($user_label, false, false, 0);
38. $user_box->pack_start($user_in, false, false, 0);
39. $pass_label = &new GtkLabel("Password: ");
40. $pass_in = &new GtkEntry();
41. $pass_box = &new GtkHBox();
42. $pass_box->pack_start($pass_label, false, false, 0);
43. $pass_box->pack_start($pass_in, false, false, 0);
44. $button1 = &new GtkButton('Generate Username:Password!');
45. $button1->connect('clicked', 'generate');
46. $output = &new GtkText();
47. $button2 = &new GtkButton('Write To File');
48. $button2->connect('clicked', 'write');
49. $vbox = &new GtkVBox();
50. $vbox->pack_start($user_box);
51. $vbox->pack_start($pass_box);
52. $vbox->pack_start($button1);
53. $vbox->pack_start($output);
54. $vbox->pack_start($button2);
55. $window->add($vbox);
56. $window->show_all();
57. Gtk::main();
58. ?>

Figure 12-8. password_gen.php

Script 12-6. password_gen.php Line-by-Line Explanation LINE
DESCRIPTION

2
If the GTK class has not been defined, then execute lines 3–7. If the GTK class has been defined, then the script needs to do nothing.

3
Check the first three characters of the PHP_OS environment variable.

4
If it is WIN, then the system is running Windows. Load the PHPGTK library for Windows.

5–7
If the PHP_OS environment variable is not WIN, then assume that PHP is running on a Linux system and load the Linux PHPGTK library.

8–10
Define a function, destroy(), that stops the script when called.

9
Execute the Gtk::main_quit() method to stop the script and close the GTK window.

10
End the function declaration.

11–17
Define a function, generate(), that encrypts a username/password combination entered by the user and prints it to a text box inside the application.

12
Assign the $user_in, $pass_in, and $output variables as global so that they can be used inside this function.

13
Assign the user-entered username and password to the $text variable.

14
Insert the username and encoded password into the text box using the insert() method for the text object. insert() takes four arguments:

Font— A GDK Font object.

Color— A GDK color object.

Size— The number of characters you wish to insert.

String— The text to be inserted.

For simplicity, I set the first three arguments as null so that the default values are used.

15
Clear the user-entered text in the Username field by inserting a blank string into the entry box.

16
Clear the user-entered text in the Password field by inserting a blank string into the entry box.

17
End the function declaration.

18–20
Define a function, $encode, that encodes the entered password.

19
Encode the password using the md5() function and return it to the calling function. You can change the encryption method to suit your needs (for example by using the crypt() function).

20
End the function declaration.

21–30
Define a function, write(), that writes the encoded username/passwords to a file.

22
Assign the $output variable as global so that it can be used inside this function.

23
Get the entire text from the text object using the get_chars() method and place it into the $text variable. The get_chars() method takes two arguments:

The start position of the text (0 is the first position).

The end position of the text.

Using 0 and -1 as arguments causes the entire text in the text object to be collected.

24
Open a file for writing. Note that if you have an existing file with the same name, it will be written over with the new username/password combos. You must also set permissions on the file so that it can be written to by PHP.

25
Write the text to the file.

26
Close the file.

27
Delete the text in the text area.

28
Create a string of text notifying the user that the text has been written.

29
Write the string to the text area. Note that you will need to close and restart the application if you wish to create passwords again.

30
End the function declaration.

31
Create a new window object called $window.

32
Set the size of the window to be 300 x 300 pixels.

33
Connect the 'destroy' method of the window to the destroy() function that you defined earlier. The 'destroy' method is called when the user clicks the "X" on the top right of the window.

34
Create a new label object for the username label.

35
Create a new text-entry object for the username.

36
Create a new hbox in which to place the username label and text-entry objects.

37
Pack the label object into the hbox.

38
Pack the text-entry object into the hbox.

39
Create a new label object for the password label.

40
Create a new text-entry object for the password.

41
Create a new hbox in which to place the password label and text-entry objects.

42
Pack the label object into the hbox.

43
Pack the text-entry object into the hbox.

44
Create a new button object for the "Generate…" button.

45
Connect the "Generate…" button to the generate() function.

46
Create a new text object to display the output.

47
Create a new button object for the "Write To File" button.

48
Connect the "Write To File" button to the write() function.

49
Create a new vbox to hold the other boxes and buttons.

50
Pack the hbox containing the Username label and entry into the vbox.

51
Pack the hbox containing the Password label and entry into the vbox.

52
Pack the "Generate…" button into the vbox.

53
Pack the text object into the vbox.

54
Pack the "Write To File" button into the vbox.

55
Add the vbox to the window.

56
Show all of the contents of the window.

57
Execute the script.

0 comments: