The $errors string is set to the value of given code (NUM1_MISSING) for the cho- sen language (set using LANGUAGE in the calc2.conf configuration file). Since we have defined LANGUAGE constant as follows in calc2.conf: define(LANGUAGE, ‘US’); The U.S. language versions of error messages are selected. However, if you wanted to choose the Spanish language (ES) version of error messages, all you have to do is set LANGUAGE to ES in calc2.conf and uncomment the ES version of error codes in calc2.errors file. To save memory you can comment out the U.S. version of the error code or remove them if wanted. In most applications in this book we define $DEFAULT_LANGUAGE as the language configuration for applications. So you see how a simple configuration change can switch the language of a script from English to Spanish. You can access a large number of major languages using this method. We translated the U.S. English to Spanish using Google’s language transla- tion service and therefore the accuracy of the translation is not verified. In larger application, you will not only have error messages but also messages that are shown in dialog windows or status screens. In such case you can use the exact same type of configuration files to load messages. In most of the applications throughout the books we use app_name.messages for dialog/status messages and app_name.errors for error messages. Using relational database If you need to store data, strongly consider using a relational database. My experi- ence shows that, in the beginning of most projects, developers decide whether to use a database based on available data, complexity of managing data, and expected growth rate of data. Initially, all of these seem trivial in many projects and, there- fore, a flat file or comma-separated values (CSV) files–based data store is elected for quick and dirty jobs. If you have access to a fast database such as MySQL, strongly consider storing your application data in the database. The benefits of a database like MySQL are almost unparalleled when compared with other data-storage solutions. Chapter 1: Features of Practical PHP Applications 21 03 549669 ch01.qxd 4/4/03 9:24 AM Page 21 Using portable directory structure When designing the directory structure of your application, consider a portable one. A portable directory structure is one that is easy to deploy and avoids hard- coded fully qualified paths whenever possible. Almost all the applications in this book use the following portable directory structure: %DocumentRoot% | + app_name | + apps | + class | + templates For example, the calendar application in Chapter 10 uses the following: %DocumentRoot% | + framework | + pear | + phplib | + calendar | + apps | + class | + templates This directory structure can be created using the following PHP code // If you have installed PEAR packages in a different // directory than %DocumentRoot%/pear change the setting below. $PEAR_DIR = $_SERVER[‘DOCUMENT_ROOT’] . ‘/pear’ ; // If you have installed PHPLIB in a different // directory than %DocumentRoot%/phplib, change the setting below. $PHPLIB_DIR = $_SERVER[‘DOCUMENT_ROOT’] . ‘/phplib’; 22 Part I: Designing PHP Applications 03 549669 ch01.qxd 4/4/03 9:24 AM Page 22 // If you have installed framewirk directory in a different // directory than %DocumentRoot%/framework, change the setting below. $APP_FRAMEWORK_DIR = $_SERVER[‘DOCUMENT_ROOT’] . ‘/framework’; //If you have installed this application in a different // directory than %DocumentRoot%, chance the settings below. $ROOT_PATH = $_SERVER[‘DOCUMENT_ROOT’]; $REL_ROOT_PATH = ‘/calendar’; $REL_APP_PATH = $REL_ROOT_PATH . ‘/apps’; $TEMPLATE_DIR = $ROOT_PATH . $REL_APP_PATH . ‘/templates’; $CLASS_DIR = $ROOT_PATH . $REL_APP_PATH . ‘/class’; $REL_TEMPLATE_DIR = $REL_APP_PATH . ‘/templates/’; The key point is that you should avoid hard-coding a fully qualified path in the application so that deployment of your application is as hassle-free as it can be. For example, say you have developed the application on your Web server with the fol- lowing directory structure: /usr/local/apache/htdocs | + your_app | + templates If /usr/local/apache/htdocs is your Web server’s document root (%DocumentRoot%), make sure that you haven’t hard-coded it in the configuration. If you use $TEMPLATE_DIR to point to your template directory in your_app.conf, you should use the following: $ROOT_PATH = $_SERVER[‘DOCUMENT_ROOT’]; $REL_ROOT_PATH = ‘/your_app; $TEMPLATE_DIR = $ROOT_PATH . ‘/templates’; Instead of: $TEMPLATE_DIR = ‘/usr/local/apache/htdocs/your_app/templates’; The benefit of the non-hard-coded version is that if you created a tar ball or a zip file of your entire application and gave it to another user whose Web document root is set to something else, she doesn’t have to change your application configu- ration for fixing paths as long as she installs the application in the %DocumentRoot%/your_appsee directory. Chapter 1: Features of Practical PHP Applications 23 03 549669 ch01.qxd 4/4/03 9:24 AM Page 23 Using access control If your PHP application is deployed on a site where unauthorized use is possible, you have to implement access control. Access control can be established using two methods: ◆ Authentication, such as restriction using username/password. You can learn more about this in detail in Chapter 5. ◆ Authorization, such as IP/network address allow/deny control. You can learn more about this in detail in Chapter 22. You can deploy one or both of these techniques in developing a comprehensive access control for sensitive applications. Summary In this chapter, you learned about the features of a practical PHP application. When you write an application that uses external configuration files, template-based interface, and database for storage in an object-oriented manner, you are likely to have a well-structured, maintainable application. 24 Part I: Designing PHP Applications 03 549669 ch01.qxd 4/4/03 9:24 AM Page 24 Chapter 2 Understanding and Avoiding Security Risks IN THIS CHAPTER ◆ Identifying sources of risks ◆ Minimizing user-input risks ◆ Running external programs safely ◆ Acquiring user input in a safe manner ◆ Protecting sensitive information BEFORE YOU CAN DESIGN secure PHP applications, you have to understand the secu- rity risks involved and know how to deal with them. In this chapter, we will discuss the most common risks involved with Web-based PHP applications. Identifying the Sources of Risk The sources of most security problems are user input, unprotected security infor- mation, and unauthorized access to applications. Among these risk factors, user input stands out the most, and it is also the most exploited to make unauthorized, unintended use of applications. A poorly written PHP application that handles user input as safe data provides ample opportunity for security breaches quite easily. Sensitive data is often made available unintentionally by programs to people who should not have any access to the information. Such exposure can result in disaster if the information falls in the hands of a malicious hacker. Unauthorized access is difficult to deal with if users can’t be authenticated using user names and passwords and/or hostname/IP address based access control cannot be established. User authentication and access control are covered in detail in Chapter 5 and Chapter 22 so we will not discuss them here. In the following sections, we discuss these risks and potential solutions in detail. 25 04 549669 ch02.qxd 4/4/03 9:24 AM Page 25 . have installed PHPLIB in a different // directory than %DocumentRoot%/phplib, change the setting below. $PHPLIB_DIR = $_SERVER[‘DOCUMENT_ROOT’] . ‘/phplib’; 22 Part I: Designing PHP Applications 03. DESIGN secure PHP applications, you have to understand the secu- rity risks involved and know how to deal with them. In this chapter, we will discuss the most common risks involved with Web-based PHP. the %DocumentRoot%/your_appsee directory. Chapter 1: Features of Practical PHP Applications 23 03 549669 ch01.qxd 4/4/03 9:24 AM Page 23 Using access control If your PHP application is deployed on a site where unauthorized