xref: /PHP-5.4/sapi/apache_hooks/README (revision 010fd97a)
1This is very beta documentation.  Clearly better stuff can and will follow.
2
3INTRO:
4
5apache_hooks is a full super-set enhancement of the apache 1.3 sapi that allows for
6php code to be run on the apache request object at every stage of the apache
7request.  It supports all of the apache 1.3 sapi commands and configurations, and
8additionally supports the following httpd.conf directives:
9
10
11HTTPD.CONF DIRECTIEVS:
12
13phpRequire /path/to/file  = requires a file at the beginning of an
14initial apache request
15
16phpUriHandler /path/to/file  = registers a hook that will run the
17specified file at the uri translation stage of the apache request
18phpUriHandler Class::Method = registers a hook to run  Class::Method at
19the uri translation stage of the apache request
20
21phpPostReadHandler /path/to/file = hook for post-read phase
22phpPostReadHandlerMethod Class::Method
23
24phpHeaderHandler  = hook for header parsing phase
25phpHeaderHandlerMethod
26
27phpAuthHandler = hook for authentication phase
28phpAuthHandlerMethod
29
30phpAccessHandler = hook for access control phase
31phpAccessHandlerMethod
32
33phpTypeHandler = hook for Type Checking phase
34phpTypeHandlerMethod
35
36phpFixupHandler = hook for 'fixup' phase
37phpFixupHandlerMethod
38
39phpLoggerHandler = hook for logging phase
40phpLoggerHandlerMethod
41
42AddHandler php-script   =  set's up a special type handler
43phpResponseHandler  /path/to/file  = sets file to be called to handle
44response phase
45phpResponseHandlerMethod Class::Method
46
47
48All handlers may be stacked, i.e. you can list multiple handler directives
49in a single scope and they will be run in order.
50
51
52EXAMPLES:
53
54So, to set up a 'hello world' location handler (so that any request to
55/hello/* returns hello world) you can:
56
57phpRequire /tmp/setup.php
58<Location /hello>
59AddHandler php-script
60phpResponseHandlerMethod Hello::World
61</Location>
62
63with
64#/tmp/setup.php
65<?
66class Hello {
67         function World() {
68                 global $request;
69                 $request->send_http_header();
70                 echo "Hello World";
71         }
72}
73?>
74
75$request is the apache request.  It is instantiated at all stages
76automatically.  The methods of that class are:
77
78getallheaders
79args
80boundary
81content_encoding
82content_type
83filename
84handler
85hostname
86method
87path_info
88protocol
89status_line
90the_request
91unparsed_uri
92uri
93allowed
94bytes_sent
95chunked
96content_length
97header_only
98method_number
99mtime
100no_cache
101no_local_copy
102proto_num
103proxyreq
104read_body
105remaining
106request_time
107status
108headers_in
109headers_out
110err_headers_out
111auth_name
112auth_type
113basic_auth_pw
114discard_request_body
115is_initial_req
116meets_conditions
117remote_host
118satisfies
119server_port
120set_etag
121set_last_modified
122some_auth_required
123update_mtime
124send_http_header
125basic_http_header
126send_header_field
127send_http_trace
128send_http_options
129send_error_response
130set_content_length
131set_keepalive
132rputs
133log_error
134lookup_uri
135lookup_file
136method_uri
137run
138internal_redirect
139
140
141These all wrap the ap_* apache EXPORT_API functions using the same
142semantics (and are also the same as the Apache::Request methods in
143mod_perl if you are familiar with that)
144
145So, a uri handler to redirect all non-local traffic to /404.php (an
146error page) would be
147
148phpUriHandler  /tmp/uri.php
149
150#/tmp/uri.php
151<?
152        if($REMOTE_ADDR != '127.0.0.1') {
153                $request->uri('/404.php');
154        }
155        return OK;
156?>
157
158It's important to note that since this is called from the uri
159translations phase, this validation is performed for every request to
160the server, not just for php pages.
161
162Also, scope is shared between all the hooks.  So in the above, we could
163merge the two and do something like:
164
165#/tmp/uri.php
166<?
167        if($REMOTE_ADDR != '127.0.0.1') {
168                $whoami = 'Stranger';
169        }
170        else {
171                $whoami = 'Friend';
172        }
173        return DECLINED;  # because we're not redirecting, just messing around
174?>
175
176and then:
177
178#/tmp/setup.php
179<?
180class Hello {
181         function World() {
182                 global $request;
183                 global $whoami;
184                 $request->send_http_header();
185                 echo "Hello $whoami";
186         }
187}
188?>
189
190These variables are also in the same scope as a script if your script is
191being handled by the standard application/x-httpd-php handler.
192
193This allows you to make decisions and pass data between your handlers
194and scripts at all stages.
195
196The above are clearly trite examples, but hopefully give you a starting
197point.
198
199One note:  all handlers can be validly re-entered 'in sub-requests'.
200For this reason you should not define functions/classes here without
201anti-redefinition guards (I would just recommend putting them in an
202include and using include_one).  This is not true for phpRequire, which
203is only entered once, at the main request, and so it is safe to make
204function/class declarations there (in fact that's what it's for).
205
206Hope that helps!
207