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