How does PHP set HTTP headers with the header() function? - php

I am learning HTTP and web programming and I was surprised to find out that you can set HTTP headers using php. I thought PHP was used to generate dynamic HTML web pages and create applications. It seems strange to me that PHP can set headers that are sent by the web server (e.g. Apache). I know PHP interpreter reads the PHP file and generates an output usually in the form of HTML.
Does this process work with pipes? In my opinion the apache server has to be able to receive commands from the PHP interpreter or it has to be able to interpret PHP functions itself. They are separate processes I think.
What mechanism is used by PHP to set headers to the web server application (httpd or Apache or something else)
Do all web servers support receiving and setting headers that are received via PHP?
Is it possible to set HTTP headers with all backend languages?
I searched through the website and I did not find an aswer to my question.
More specifically I want to know what command can apache or other web server send to PHP.exe application or PHP-CGI.exe application to receive other information besides the outputted HTML file.

Indeed an interesting question. Using command-line tools, I can only access the produced HTML output. Hence php -r"header('Location: http://someurl.com');" will produce nothing from command line.
When I would look at my setup with IIS (not Apache) though, I see that IIS is using PHP-CGI.exe to communicate with PHP. Looking at the optional arguments of PHP-CGI.exe, I see -b can be used to set a Bind Path for external FASTCGI Server mode. I guess in this server mode there will be room to communicate header information separate from produced HTML.
I don't know the exact details of the FASTCGI protocols to go more indepth. But I guess this is what you wanted to know.
EDIT:
When googling about this, I came upon this thread:
How does PHP interface with Apache?

Sending headers from PHP is very useful, for example, you can send headers that force the browser to download a file vs. displaying it on screen (for file scripts, reports that output CSV), controlling cache headers and performing page redirection.
As stated in one of the comments, PHP being a module of Apache in many installs, it sends headers directly through that. Otherwise, the headers would be sent via CGI / FastCGI, or PHP-FPM for nginx.
What you're thinking of more or less is of a templating engine, which PHP performs well at, but PHP has other functions that would normally not be seen in a template engine, such as opening sockets, handling files, and so on.
Any backend language I've had experience with has support for sending HTTP headers, and I would consider any web-oriented back-end language incomplete without this ability.

header('Location: http://www.google.com/');
In this way we can set header in php

Related

Is it possible to enable HTTP range request support in the PHP's built-in web server?

I'm using the PHP built-in server to serve static files.
php -S localhost:8000
I have however noticed that the Range header gets ignored - instead of serving the requested range, the entire resource is served.
I am not that well versed in PHP, the reason I'm using this server is because I'm looking for an alternative to Python's built-in server (python3 -m http.server) which does not support range requests (either?) that is built-in into macOS. It seems to me like Python and PHP servers are the two available options. Knowing Python's doesn't support HTTP range requests, is there any way to use config.ini or some other mechanism to enable HTTP range requests in PHP's?
I looked at php -h but it doesn't talk about the -S option much beyond the basic syntax. Not sure if there are more options that can be used with it so that's why I assume config.ini is the only possible way.
If you start the webserver with a router:
$ php -S 0.0.0.0:9999 router.php
All http requests will be passed through that script. And in there you can handle the range request by reading and outputing chunks of files.
Using the script linked to here in this comment:
https://stackoverflow.com/a/22398156/3392762
You can try something like the following in router.php:
<?php
if($_SERVER['REQUEST_URI'] === '/foo.ogg')
serveFilePartial('foo.ogg');
Be very careful mapping user submitted paths to files.
I can't attest to the quality of the linked code. But if you scan it, it looks for the $_SERVER['HTTP_RANGE'] header. And tries to grab the byte range requested and serve a chunk appropriately.
Although I don't have a definitive answer I'm pretty sure the documentation essentially says no.
This web server was designed to aid application development. It may also be useful for testing purposes or for application demonstrations that are run in controlled environments. It is not intended to be a full-featured web server.

PHP redirect file post stream

I'm writing an API using php to wrap a website functionality and returning everything in json\xml. I've been using curl and so far it's working great.
The website has a standard file upload Post that accepts file(s) up to 1GB.
So the problem is how to redirect the file upload stream to the correspondent website?
I could download the file and after that upload it, but I'm limited by my server to just 20MG. And it seems a poor solution.
Is it even possible to control the stream and redirect it directly to the website?
I preserverd original at the bottom for posterity, but as it turns out, there is a way to do this
What you need to use is a combination of HTTP put method (which unfortunately isn't available in native browser forms), the PHP php://input wrapper, and a streaming php Socket. This gets around several limitations - PHP disallows php://input for post data, but it does nothing with regards to PUT filedata - clever!
If you're going to attempt this with apache, you're going to need mod_actions installed an activated. You're also going to need to specify a PUT script with the Script directive in your virtualhost/.htaccess.
http://blog.haraldkraft.de/2009/08/invalid-command-script-in-apache-configuration/
This allows put methods only for one url endpoint. This is the file that will open the socket and forward its data elsewhere. In my example case below, this is just index.php
I've prepared a boilerplate example of this using the python requests module as the client sending the put request with an image file. If you run the remote_server.py it will open a service that just listens on a port and awaits the forwarded message from php. put.py sends the actual put request to PHP. You're going to need to set the hosts put.py and index.php to the ones you define in your virtual host depending on your setup.
Running put.py will open the included image file, send it to your php virtual host, which will, in turn, open a socket and stream the received data to the python pseudo-service and print it to stdout in the terminal. Streaming PHP forwarder!
There's nothing stopping you from using any remote service that listens on a TCP port in the same way, in another language entirely. The client could be rewritten the same way, so long as it can send a PUT request.
The complete example is here:
https://github.com/DeaconDesperado/php-streamer
I actually had a lot of fun with this problem. Please let me know how it works and we can patch it together.
Begin original answer
There is no native way in php to pass a file asynchronously as it comes in with the request body without saving its state down to disc in some manner. This means you are hard bound by the memory limit on your server (20MB). The manner in which the $_FILES superglobal is initialized after the request is received depends upon this, as it will attempt to migrate that multipart data to a tmp directory.
Something similar can be acheived with the use of sockets, as this will circumvent the HTTP protocol at least, but if the file is passed in the HTTP request, php is still going to attempt to save it statefully in memory before it does anything at all with it. You'd have the tail end of the process set up with no practical way of getting that far.
There is the Stream library comes close, but still relies on reading the file out of memory on the server side - it's got to already be there.
What you are describing is a little bit outside of the HTTP protocol, especially since the request body is so large. HTTP is a request/response based mechanism, and one depends upon the other... it's very difficult to accomplish a in-place, streaming upload at an intermediary point since this would imply some protocol that uploads while the bits are streamed in.
One might argue this is more a limitation of HTTP than PHP, and since PHP is designed expressedly with the HTTP protocol in mind, you are moving about outside its comfort zone.
Deployments like this are regularly attempted with high success using other scripting languages (Twisted in Python for example, lot of people are getting onboard with NodeJS for its concurrent design patter, there are alternatives in Ruby or Java that I know much less about.)

How are php files secured

I was wondering how php files are actually secured. How come one can not download a php file, even if the exact location is known?
When I upload a php file to my webserver, lets say to domain.com/files, and I call the domain.com/files page, I can clearly see the php file and its actual size. Downloading the file however leads to an empty file.
The question then is: How does the security mechanism work exactly?
The web server's responsibility is to take the PHP script and hand it to the PHP interpreter, which sends the HTML (or other) output back to the web server.
A mis-configured web server may fail to handle the PHP script properly, and send it down to the requesting browser in its raw form, and that would make it possible to access PHP scripts directly.
Your web hosting may have a mechanism to list the contents of a directory, but the unless it supplies a download mechanism to supply the PHP script with plain text headers (as opposed to HTML) without handing it to the PHP interpreter, it will be executed as PHP rather than served down.
In order to be able to download the raw PHP file, the server would have to do some extra work (possibly via another PHP script) which reads the PHP file from disk and sends its contents down to the browser with plain text headers.
When you request domain.com/files your web server is setup to show all the files in that directory.
When you request the actual php file the web server executes it and outputs the results back to you - not the source code.
Of course, both of the above can be configured. You could switch of directory listing and disable parsing of php files so the actual file contents/source code is output.
Its usually a good practice to switch off directory listing.
When you first install PHP on your server, it reconfigures Apache so that when a .php file is requested, Apache hands processing over to PHP. PHP then processes the code in the file, and returns whatever text the PHP code echoed or printed to Apache, which then sends that back over the network to the person that requested the PHP file.
The "security" comes simply in that Apache does not simply serve the PHP file, but rather hands it over to the PHP processor for execution. If Apache is not configured correctly or you use a server software that does not recognize PHP, the raw PHP file will be sent to the client.
Short answer: since the server is configured to execute PHP files and return the results, you will never be able to access the PHP source from the outside. All code is executed immediately by the server. So, to answer your question:
The security mechanism is that .php files are executed automatically by the server when they are requested.
This is a huge misconception. When you attempt to access a PHP file over port 80, your request is likely being run through a web server which does something with the file. In the case of PHP, it runs that file through the PHP interpreter, which causes that file to create some output, and that is what is sent to you.
You can easily allow downloading of PHP files by removing the interpreter for that file type. If the web server doesn't have anything special for it and doesn't understand the file, it will just have the client download it.

Parsing PHP content in HTML without Webserver

I want to create a simple webiste with only html pages. I am now including Header, sidebar, footer in every file, which is redundant. So, while looking for solution, I found <?php include, can help me. But my browser is not parsing php content. How can I make it parse php files in html?
Thank you
Since your goal is to create a simple HTML website, with static pages I don't think PHP is the best way to go.
You have two options:
Run PHP on your local computer to pre-process the files:
If you install PHP-cli (command line client), you can use it to process your PHP static pages. Redirect its output to a file and you have your desired output:
php-cli index.php > index.html
Use nanoc (ruby-based) to build your static website:
If you don't have a webserver with PHP enabled, I assume you do not have PHP as a requirement but rather found about <?php include('file') ?> while studying HTML.
With this in mind, I suggest you check out nanoc. It's a tool what uses ruby to help creating static HTML webpages, by providing ways to define a layout (what you're doing with PHP's include) and many other features.
It's quite simple to use and produces static HTML files that you can upload to any server or open with your browser directly and still enables many powerful features while developing your website.
You need to have PHP installed on the server that is running the website. You need to make sure you are naming your files with a valid php extension, e.g. index.php. Can you give us a link to your website where the issue is occurring?
When you enter www.example.com/test.php in the addressbar,the browser contacts the webserver at www.example.com and requests for the file /test.php. Now depending on how your server is configured, you web server will detect the type of the file (usually using the extension). In this case (since the extension is .php), the webserver will detect that the file is a PHP script and will invoke the PHP interpreter. The PHP interpreter will execute the script and generate HTML which is passed on to the web server. Now the web server will return the HTML to the browser.
PHP is a mainly (Yes, it is possible to run PHP within browser) a server side language
This means PHP is not executed in you browser, but on your server
Therefore, you need to have PHP configured correctly on your server to see the correct output
Even if you manage to configure PHP as client side language on your system, remember there is not even < 1% change of your user's browser supporting it.
You can only have webpages, and not website, without a web server
A website (also spelled Web site) is a collection of related web pages, images, videos or other digital assets that are addressed relative to a common Uniform Resource Locator (URL), often consisting of only the domain name (or, in rare cases, the IP address) and the root path ('/') in an Internet Protocol-based network. A web site is hosted on at least one web server, accessible via a network such as the Internet or a private local area network.
You need to have a web server set up with PHP running on it. PHP is an acronym for "PHP: Hypertext Preprocessor". PHP is processed on the server, rendered into HTML content, then sent out of a web browser to be viewed, but no web browser has the ability to processor PHP on its own.
Here are some resources to get you started:
PHP: What do I need?
Your First PHP-enabled Page
Your browser cannot interpret / parse php files.
If you want to test your site locally, you will need to install a local server like WampServer for windows or apache and php in linux.

Why PHP script is not workig in a web browser?

We have all seen many question on StackOverflow that are founded upon the idea that PHP works like Javascript. Where the person clearly does not understand that PHP is a Preproccessor and only works before the page is sent out.
A clear example of this is in the following code, where runCommand() will not run when the user presses the button.
Click Me!
as it would in Javascript
Click Me!
I've seen many questions like this that are from new people that just simply don't realize 'how' PHP works.
My question is: Where is a great resource that explains how PHP works?.
I want to be able to redirect people to a page that can get them going on the correct track and know what being a Preproccessor means.
(This also allows me to be lazy and not have to write an explanation every time it comes up, but don't tell anyone!)
If you don't know of a place that describes this well, feel free to provide your own interpretation.
As Carl Smotricz points out, there is a part of PHP that can be used outside of the browser. But I'm mainly talking about in a Apache enviorment where a user requests a web page, and expects to get something back, usually in HTML.
Wikipedia is always a great resource of information. I suggest:
Server-side scripting
vs
Client-side scripting
And Wikipedia also has pictures:
It could be that you're the one who does not understand how PHP works. PHP is a full language interpreter, and it's completely possible to run PHP scripts without a browser, outside of a Web server: On the command line or in an IDE or other GUI environment.
The PHP preprocessor of which you speak is only the function of an Apache module that calls on the PHP interpreter for this particular limited purpose.
The PHP code is interpreted on the server side an only the output of your PHP code will be send to the client.
So if a PHP file is requested, the web server sends the PHP code to the PHP interpreter, waits for the output and then sends the output back to the client.
In short, PHP belongs to the server, it usually then outputs HTML but it's not here for that (or at least, not only for that).
The user browser "sees" only what remains after php did its thing.
Javascript belongs to the client (aka browser): it usually handles the DOM created by parsing the HTML, which is (possibly) produced by executing PHP. Javascript can behave differently in different browsers (everyone who has written JS scripts know about cross-browser problems, do you remember IE6?)
Javascript can't handle database all by itself; It has to rely on a sever-side language (php, maybe? ;) (except if talking about node.js)
BTW, AJAX can be a good reference to understand what exactly PHP does and what JS does.
An important distinction is that JavaScript in a browser is event driven. That is why a click handler is not executed right away as the page loads, for example. The javascript could not be waiting to respond to that click either, if it was not for the event-driven style of dom programming.
I don't really think this is what is meant by the term 'preprocessor'. the client/server side distinction is more important. For instance, have you heard of any other server side language being referred to as a preprocessor when performing the same tasks as PHP?
php responds to http requests in the typical server-side scenario. the browser reads this response and is responsible for rendering it and running any additional dynamic scripts embedded in the response on the client side. that is essentially the division of labor in that scenario.
PHP is server-side scripting language which means all php code is executed before page is sent to the client side. For that reason you will never see
<?php ... ?>
in page source.
On high abstraction level...
You can consider web server (hardware) as component of four different parts. Webserver(software, for example Apache), File system, database and PHP plugin.
So for example when you sent page request (for some page .../example.php) to the web server Apache will try to find that page in file system and if the page exists he will call php plugin to executes all
<?php ... ?>
code (of course including db queries). After that page is sent back to the client side where you can manipulate with page through JavaScript, designed it through CSS...
More on: https://www.youtube.com/watch?v=PemsuAfc7Jw
The reason why PHP scripts are not working in a web browser is only because web browsers do not support PHP (at least I don't know any). This fact is not as trivial as one may think.
And it may sound disturbing, so take a look at HTML specifications on W3C website of HTML 5 and HTML 4.01 (because it has more verbose examples). What you can find? That scripts can be written in languages other than JavaScript!
Here is an example from HTML 4.01 documentation (section titled Specifying the scripting language).
(...)
Here's a more interesting window handler:
<SCRIPT type="text/javascript">
function my_onload() {
. . .
}
var win = window.open("some/other/URI")
if (win) win.onload = my_onload
</SCRIPT>
In Tcl this looks like:
<SCRIPT type="text/tcl">
proc my_onload {} {
. . .
}
set win [window open "some/other/URI"]
if {$win != ""} {
$win onload my_onload
}
</SCRIPT>
Script written in Tcl is perfectly O.K. in HTML! What about PHP? HTML5 documentation says:
A user agent is said to support the scripting language if each
component of the script block's type is an ASCII case-insensitive
match for the corresponding component in the MIME type string of a
scripting language that the user agent implements.
(...) User agents may support other MIME types for other languages,
but must not support other MIME types for the languages in the list
above. User agents are not required to support the languages listed
above.
Thus it is only up to web browser (user agent) if it is going to support PHP or not. Playing with W3C example, PHP aware web browser might have accepted something like this.
<script type="text/php">
function my_onload() {
. . .
}
$win = $window->open('some/other/URI');
if ($win !== false)
$win->onload = 'my_onload';
</script>
So, the reason why people ask such questions is not that they don't know how PHP works. It is because they don't understand web technology in general. They fail at point, which requires understanding of what, where and why is supposed to be executed.
The PHP compiler executes in the server as a CGI script. A CGI script reads from Standard Input and writes to Standard Output, similar to a console or command prompt program. The PHP compiler reads the file containing HTML and embedded PHP and writes the HTML out and (when encountered) executes the PHP and writes the result of the PHP code. The output is received by the server then sent to the client.
See PHP: CGI and command line setups - Manual that says:
By default, PHP is built as both a CLI and CGI program, which can be used for CGI processing.
The difference between CLI and CGI are insignificant here.
Also see PHP: What is PHP? - Manual that says:
the code is executed on the server, generating HTML which is then sent to the client.
See RFC 3875 - The Common Gateway Interface (CGI) Version 1.1. It is the official definition of CGI. PHP seldom uses the original CGI protocol; other protocols such as FastCGI are used and perform the same function as the original CGI protocol but are designed to be more efficient. For the purpose of understanding how PHP works the original CGI protocol is relevant. The following is an excerpt of the RFC.
Abstract
The Common Gateway Interface (CGI) is a simple interface for running
external programs, software or gateways under an information server
in a platform-independent manner. Currently, the supported information
servers are HTTP servers.

Categories