Recipe 18.6. Keeping Passwords Out of Your Site Files18.6.1. ProblemYou need 18.6.2. SolutionStore the password in an environment variable in a file that the web server loads when starting up. Then, just reference the environment variable in your code: <?php 18.6.3. DiscussionWhile this technique removes passwords from the source code of your pages, it makes them available in other places that need to be protected. Most importantly, make sure that there are no publicly viewable pages that call phpinfo( ). Because Next, especially if you are using a shared host, make sure the environment variables are set in such a way that they are only available to your virtual host, not to all users. With Apache, you can do this by setting the variables in a separate file from the main configuration file: SetEnv DB_USER "susannah" Inside the <VirtualHost> directive for the site in the main configuration file (httpd.conf), Include "/usr/local/apache/database-passwords" Make sure that this separate file containing the password (e.g., /usr/local/apache/database-passwords) is not readable by any user other than the one that controls the appropriate virtual host. When Apache starts up and is reading in configuration files, it's usually running as root, so it is able to read the included file. A child process that handles requests typically runs as an unprivileged user, so rogue scripts cannot read the protected file. 18.6.4. See AlsoDocumentation on Apache's Include directive at http://httpd.apache.org/docs/mod/core.html#include. |
Recipe 10.3. Connecting to an SQL Database
Recipe 10.3. Connecting to an SQL Database10.3.1. ProblemYou want access to a 10.3.2. SolutionCreate a new Connecting with PDO
10.3.3. DiscussionIf all goes well, the PDO constructor returns a new object that can be used for querying the database. If there's a problem, a PDOException is thrown. As you can see from Example 10-8, the format of the DSN is highly dependent on which kind of database you're attempting to connect to. In general, though, the first argument to the PDO constructor is a string that describes the location and name of the database you want and the second and third arguments are the username and password to connect to the database with. Note that to use a particular PDO backend, PHP must be built with support for that backend. Use the output from phpinfo( ) to determine what PDO backends your PHP setup has. 10.3.4. See AlsoRecipe 10.6 for querying an SQL database; Recipe 10.6 for modifying an SQL database; documentation on PDO at http://www.php.net/PDO. |
Recipe 1.12. Generating Fixed-Width Field Data Records
Recipe 1.12. Generating Fixed-Width Field Data Records1.12.1. ProblemYou need to format 1.12.2. SolutionUse pack( ) Generating fixed-width field data records
1.12.3. DiscussionThe format string A25A14A4 tells pack( ) to transform its subsequent arguments into a 25-character space-padded string, a 14-character space-padded string, and a 4-character space-padded string. For space-padded fields in fixed-width records, pack( ) provides a concise solution. To pad fields with something other than a space, however, use Generating fixed-width field data records without pack( )
1.12.4. See AlsoDocumentation on pack( ) at http://www.php.net/pack and on str_pad( ) at http://www.php.net/str_pad. Recipe 1.16 discusses pack( ) format strings in more detail. |
Recipe 21.5. Avoiding Regular Expressions
Recipe 21.5. Avoiding Regular Expressions21.5.1. ProblemYou want to 21.5.2. SolutionReplace unnecessary regular expression calls with faster string and character type function alternatives. 21.5.3. DiscussionA common source of unnecessary computation is the use of regular expression functions when they are not needed'for example, if you're validating a A common approach to this problem is a regular expression: <?php The same test can be performed much faster with the ctype_alnum( ) Using code-timing techniques covered in Recipe 21.1, let's compare the above test with ctype_alnum( ): <?php This will output results similar to: preg_match took: 0.000163078308105 seconds ctype_alnum( ) is considerably faster; 9.05990600586E-06 is the same as 0.00000906 seconds, which is 18 times faster than the preg_match( ) regular expression, with exactly the same result. When applied to a complex application, replacing unnecessary regular expressions with equivalent alternatives can add up to a significant performance gain. A good litmus test when you're coding and need to decide whether or not you need to use a regular expression is whether or not the match you're performing can be explained in a brief sentence. Granted, there are some matches, such as "string is a valid email address," which cannot be adequately verified without a complex regular expression. However, "check if string A contains string B" can be tested with several different approaches, but is ultimately a very simple test that does not require regular expressions: $haystack = 'The quick brown fox jumps over the lazy dog'; There is certainly a benefit to double-checking the ctype and string functions before making a commitment to a regular expression, particularly if you're working a section of code that will loop repeatedly. 21.5.4. See AlsoDocumentation on ctype functions at http://www.php.net/manual/en/ref.ctype.php; on string functions at http://www.php.net/manual/en/ref.strings.php; on regular expression functions at http://www.php.net/manual/en/ref.pcre.php. |
Section 10.2. The Top-Level Environment
10.2. The Top-Level Environment
When the Ruby interpreter starts, a number of classes, modules,
constants, and global variables and global functions are defined and
available for use by programs. The subsections that follow list these
predefined features.
10.2.1. Predefined Modules and Classes
When the Ruby 1.8 interpreter starts, the following modules are
defined:
Comparable FileTest Marshal Precision
Enumerable GC Math Process
Errno Kernel ObjectSpace Signal
These classes are defined on startup:
Array File Method String
Bignum Fixnum Module Struct
Binding Float NilClass Symbol
Class Hash Numeric Thread
Continuation IO Object ThreadGroup
Data Integer Proc Time
Dir MatchData Range TrueClass
FalseClass MatchingData Regexp UnboundMethod
The following exception classes are also defined:
ArgumentError NameError SignalException
EOFError NoMemoryError StandardError
Exception NoMethodError SyntaxError
FloatDomainError NotImplementedError SystemCallError
IOError RangeError SystemExit
IndexError RegexpError SystemStackError
Interrupt RuntimeError ThreadError
LoadError ScriptError TypeError
LocalJumpError SecurityError ZeroDivisionError
Ruby 1.9 adds the following modules, classes, and
exceptions:
BasicObject FiberError Mutex VM
Fiber KeyError StopIteration
You can check the predefined modules, classes, and exceptions in
your implementation with code like this:
# Print all modules (excluding classes)
puts Module.constants.sort.select {|x| eval(x.to_s).instance_of? Module}
# Print all classes (excluding exceptions)
puts Module.constants.sort.select {|x|
c = eval(x.to_s)
c.is_a? Class and not c.ancestors.include? Exception
}
# Print all exceptions
puts Module.constants.sort.select {|x|
c = eval(x.to_s)
c.instance_of? Class and c.ancestors.include? Exception
}
10.2.2. Top-Level Constants
When the Ruby interpreter starts, the following top-level
constants are defined (in addition
to the modules and classes listed previously). A module that defines a
constant by the same name can still access these top-level constants by
explicitly prefixing them with ::. You can list the
top-level constants in your implementation with:
ruby -e 'puts Module.constants.sort.reject{|x| eval(x.to_s).is_a? Module}'
ARGF
An IO object providing access to a
virtual concatenation of files named in ARGV,
or to standard input if ARGV is empty. A
synonym for $<.
ARGV
An array containing the arguments specified on the command line. A
synonym for $*.
DATA
If your program file includes the token
__END__ on a line by itself, then this constant
is defined to be a stream that allows access to the lines of the
file following __END__. If the program file
does not include __END__, then this constant is
not defined.
ENV
An object that behaves like a hash and provides access
to the environment variable settings in effect for the
interpreter.
FALSE
A deprecated synonym for false.
NIL
A deprecated synonym for nil.
RUBY_PATCHLEVEL
A string indicating the patchlevel for the interpreter.
RUBY_PLATFORM
A string indicating the platform of the Ruby interpreter.
RUBY_RELEASE_DATE
A string indicating the release date of the Ruby interpreter.
RUBY_VERSION
A string indicating the version of the Ruby language supported by the
interpreter.
STDERR
The standard error output stream. This is the default
value of the $stderr variable.
STDIN
The standard input stream. This is the default value of the
$stdin variable.
STDOUT
The standard output stream. This is the default value of the
$stdout variable.
TOPLEVEL_BINDING
A Binding object representing the
bindings in the top-level scope.
TRUE
A deprecated synonym for true.
10.2.3. Global Variables
The Ruby interpreter predefines a number of global variables that your
programs can use. Many of these variables are special in some way. Some
use punctuation characters in their names. (The
English.rb module defines English-language
alternatives to the punctuation. Add require
'English' to your program if you want to use these verbose
alternatives.) Some are read-only and may not be assigned to. And some
are thread-local, so that each thread of a Ruby program may see a
different value of the variable. Finally, some global variables
($_, $~, and the pattern-matching
variables derived from it) are method-local: although the variable is
globally accessible, its value is local to the current method. If a
method sets the value of one of these magic globals, it does not alter
the value seen by the code that invokes that method.
You can obtain the complete list of global variables predefined by
your Ruby interpreter with:
ruby -e 'puts global_variables.sort'
To include the verbose names from the English
module in your listing, try:
ruby -rEnglish -e 'puts global_variables.sort'
The subsections that follow document the predefined global
variables by category.
10.2.3.1. Global settings
These global variables hold configuration settings and specify
information, such as command-line arguments, about the environment in
which the Ruby program is running:
$*
A read-only synonym for the ARGV
constant. English synonym: $ARGV.
$$
The process ID of the current Ruby process. Read-only.
English synonyms: $PID,
$PROCESS_ID.
$?
The exit status of the last process terminated.
Read-only and thread-local. English synonym:
$CHILD_STATUS.
$DEBUG
$-d
Set to true if the
-d or --debug options were
set on the command line.
$KCODE
$-K
In Ruby 1.8, this variable holds a string that names the
current text encoding. Its value is "NONE", "UTF8", "SJIS" or
"EUC". This value can be set with the interpreter option
-K. This variable no longer works in Ruby 1.9
and using it causes a warning.
$LOADED_FEATURES
$"
An array of strings naming the files that have been
loaded. Read-only.
$LOAD_PATH
$:
$-I
An array of strings holding the directories to be searched
when loading files with the load and
require methods. This variable is read-only,
but you can alter the contents of the array to which it refers,
appending or prepending new directories to the path, for
example.
$PROGRAM_NAME
$0
The name of the file that holds the Ruby program currently
being executed. The value will be "-" if the
program is read from standard input, or "-e"
if the program was specified with a -e
option. Note that this is different from
$FILENAME.
$SAFE
The current safe level for program execution. See Section 10.5
for details. This variable may be set from the command line with
the -T option. The value of this variable is
thread-local.
$VERBOSE
$-v
$-w
True if the -v, -w,
or --verbose command-line option is
specified. nil if -W0 was
specified. false otherwise. You can set this
variable to nil to suppress all
warnings.
10.2.3.2. Exception-handling globals
The following two global variables are useful in
rescue clauses when an exception has been
raised:
$!
The last exception object raised. The exception
object can also be accessed using the =>
syntax in the declaration of the rescue
clause. The value of this variable is thread-local. English
synonym: $ERROR_INFO.
$@
The stack trace of the last exception, equivalent to
$!.backtrace. This value is thread-local.
English synonym: $ERROR_POSITION.
10.2.3.3. Streams and text-processing globals
The following globals are IO streams and variable that
affect the default behavior of text-processing
Kernel methods. You'll find examples of their use
in Section 10.3:
$_
The last string read by the Kernel
methods gets and readline.
This value is thread-local and method-local. A number of
Kernel methods operate implicitly on
$_. English synonym:
$LAST_READ_LINE.
$<
A read-only synonym for the ARGF
stream: an IO-like object providing access to
a virtual concatenation of the files specified on the
command-line, or to standard input if no files were specified.
Kernel read methods, such as
gets, read from this stream. Note that this
stream is not always the same as $stdin.
English synonym: $DEFAULT_INPUT.
$stdin
The standard input stream. The initial value of this
variable is the constant STDIN. Many Ruby
program read from ARGF or
$< instead of
$stdin.
$stdout
$>
The standard output stream, and the destination of the
printing methods of Kernel: puts,
print, printf, etc.
English synonym: $DEFAULT_OUTPUT.
$stderr
The standard error output stream. The initial value of this variable
is the constant STDERR.
$FILENAME
The name of the file currently being read from
ARGF. Equivalent to
ARGF.filename. Read-only.
$.
The number of the last line read from the current input file.
Equivalent to ARGF.lineno. English synonyms:
$NR,
$INPUT_LINE_NUMBER.
$/
$-0
The input record separator (newline by default).
gets and readline use this
value by default to determine line boundaries. You can set this
value with the -0 interpreter option. English
synonyms: $RS,
$INPUT_RECORD_SEPARATOR.
$\
The output record separator. The default value is
nil, but is set to $/ when
the interpreter option -l is used. If
non-nil, the output record separator is
output after every call to print (but not
puts or other output methods). English
synonyms: $ORS,
$OUTPUT_RECORD_SEPARATOR.
$,
The separator output between the arguments to
print and the default separator for
Array.join. The default is
nil. English synonyms:
$OFS, $OUTPUT_FIELD_SEPARATOR.
$;
$-F
The default field separator used by split. The
default is nil, but you can specify a value
with the interpreter option -F. English
synonyms: $FS,
$FIELD_SEPARATOR.
$F
This variable is defined if the Ruby interpreter is invoked with
the -a option and either
-n or -p. It holds the
fields of the current input line, as returned by
split.
10.2.3.4. Pattern-matching globals
The following globals are thread-local and method-local and are
set by any Regexp pattern-matching
operation:
$~
The MatchData object produced by
the last pattern matching operation. This value is thread-local
and method-local. The other pattern-matching globals described
here are derived from this one. Setting this variable to a new
MatchData object alters the value of the
other variables. English synonym:
$MATCH_INFO.
$&
The most recently matched text. Equivalent to
$~[0]. Read-only, thread-local, method-local,
and derived from $~. English synonym:
$MATCH.
$`
The string preceding the match in the last pattern match. Equivalent to
$~.pre_match. Read-only, thread-local,
method-local, and derived from $~. English
synonym: $PREMATCH.
$'
The string following the match in the last pattern match.
Equivalent to $~.post_match Read-only,
thread-local, method-local, and derived from
$~. English synonym:
$POSTMATCH.
$+
The string corresponding to the last successfully matched
group in the last pattern match. Read-only, thread-local,
method-local, and derived from $~. English
synonym:
$LAST_PAREN_MATCH.
10.2.3.5. Command-line option globals
Ruby defines a number of global variables that correspond to the
state or value of interpreter command-line options. The variables
$-0, $-F,
$-I, $-K,
$-d, $-v, and
$-w have synonyms and are included in the previous
sections:
$-a
true if the interpreter option
-a was specified; false
otherwise. Read-only.
$-i
nil if the interpreter option
-i was not specified. Otherwise, this
variable is set to the backup file extension specified with
-i.
$-l
true if the -l
option was specified. Read-only.
$-p
true if the interpreter option
-p was specified; false
otherwise. Read-only.
$-W
In Ruby 1.9, this global variable specifies the current
verbose level. It is 0 if the -W0 option was used, and is
2 if any of the options
-w, -v, or
--verbose were used. Otherwise, this variable
is 1. Read-only.
10.2.4. Predefined Global Functions
The Kernel module, which is included by
Object, defines a number of private instance methods
that serve as global functions. Because they are private, they must be
invoked functionally, without an explicit receiver object. And because
they are included by Object, they can be invoked
anywhere—no matter what the value of self is, it will
be an object, and these methods can be implicitly invoked on it. The
functions defined by Kernel can be grouped into
several categories, most of which are covered elsewhere in this chapter
or elsewhere in this book.
10.2.4.1. Keyword functions
The following Kernel functions behave like
language keywords and are documented elsewhere in this book:
block_given? iterator? loop require
callcc lambda proc throw
catch load raise
10.2.4.2. Text input, output, and manipulation functions
Kernel defines the following functions most
of which are global variants of IO methods. They
are covered in more detail in Section 10.3:
format print puts sprintf
gets printf readline
p putc readlines
In Ruby 1.8 (but not 1.9), Kernel also
defines the following global variants of String
methods that operate implicitly on $_:
chomp chop gsub scan sub
chomp! chop! gsub! split sub!
10.2.4.3. OS methods
The following Kernel functions allow a Ruby
program to interface with the operating system. They are
platform-dependent and are covered in Section 10.4. Note that
` is the specially named backtick method that
returns the text output by an arbitrary OS shell command:
` fork select system trap
exec open syscall test
10.2.4.4. Warnings, failures, and exiting
The following Kernel functions display
warnings, raise exceptions, cause the program to exit, or register
blocks of code to be run when the program terminates. They are
documented along with OS-specific methods in Section 10.4:
abort at_exit exit exit! fail warn
10.2.4.5. Reflection functions
The following Kernel functions are part of
Ruby's reflection API and were described in Chapter 8:
binding set_trace_func
caller singleton_method_added
eval singleton_method_removed
global_variables singleton_method_undefined
local_variables trace_var
method_missing untrace_var
remove_instance_variable
10.2.4.6. Conversion functions
The following Kernel functions attempt to
convert their arguments to a new type. They were described in Section 3.8.7.3:
Array Float Integer String
10.2.4.7. Miscellaneous Kernel functions
The following miscellaneous Kernel functions
don't fit into the previous categories:
autoload rand srand
autoload? sleep
rand and srand are for
generating random numbers, and are documented in Section 9.3.7. autoload and
autoload? are covered in Section 7.6.3. And sleep is covered in
Section 9.9 and Section 10.4.4.
10.2.5. User-Defined Global Functions
When you define a method with def inside a
class or module declaration and do
not specify a receiver object for the method, the method is created as a
public instance method of self, where
self is the class or module you are defining. Using
def at the top level, outside of any
class or module, is different in
two important ways. First, top-level methods are instance methods of
Object (even though self is not
Object). Second, top-level methods are always
private.
Top-Level self: the Main ObjectBecause top-level methods become instance methods of |
The fact that top-level methods are defined in
Object means that they are inherited by all objects
(including Module and Class) and
(if not overridden) can be used within any class or instance method
definition. (You can review Ruby's method name resolution algorithm in
Section 7.8 to convince yourself of this.) The fact
that top-level methods are private means that they must be invoked like
functions, without an explicit receiver. In this way, Ruby mimics a
procedural programming paradigm within its strictly object-oriented
framework.
Recipe 21.4. Stress Testing Your Web Site
Recipe 21.4. Stress Testing Your Web Site21.4.1. ProblemYou want 21.4.2. SolutionUse a stress-testing and benchmarking tool to simulate a variety of load levels. 21.4.3. DiscussionStress testing is frequently confused with benchmarking, and it is important to recognize the difference between the two activities. Benchmarking a web site is often a somewhat casual activity when performed by an individual developer. The most commonly used tool is the % /usr/bin/ab -n 1000 -c 100 -k This test would return a report illustrating the average response time for requests to http://www.example.com/test.php, based on 1,000 requests, grouped in batches of 100 concurrent requests. While that sort of test has value'it gives you a reasonable estimation of how many requests you can serve per second under normal load'it doesn't tell you much about how your entire web application will behave under heavy load. It only pounds on one URL at a time, after all. Stress testing is a testing technique whose intent is to break your web application. By testing to a breaking point, you can identify and repair weaknesses in your application, or gain a better understanding of when you will need to add additional hardware. When combined with code profiling, you can also get an idea of what part of your application will need to scale first; i.e., will you need to add more servers to your database cluster before you need to add more frontend web server machines? An excellent open source tool for stress testing is Siege. Siege can be configured to read a large number of URLs from a configuration file and run through them in order (regression testing), or it can read a list or URLs and hit them randomly, which better approximates real-world usage of a web site. Siege can also pound on a single URL in a similar fashion to ab. If you are unable to install Siege on your system, Lincoln Stein's torture.pl script is a good alternative. Many of Siege's design concepts were inspired by torture.pl, and the two tools produce similar reports. 21.4.4. See AlsoSource and documentation for Siege at http://www.joedog.org/JoeDog/Siege; ab at http://httpd.apache.org/docs/2.0/programs/ab.html; source and documentation for torture.pl at http://stein.cshl.org/~lstein/torture/. |