DEV Community

Cover image for Publishing my blog using HTTP upload in PHP

Publishing my blog using HTTP upload in PHP

gabbersepp profile image Josef Biehler Updated on ・3 min read

In the last article I wrote about how to publish a website with travis and FTP. First everything seemed fine but the nightly build suddenly failed. It took long time until I realized that this was not because of my code or my ftp server but because of how travis has setup it's network layers. Read on here if you are interested:

But the fight is not lost! My webspace paket includes a PHP instance and thus I am able to write a small HTTP upload tool. A bit oversized I think but it enables me to continue using my webspace bundle.

The PHP fileupload

Shame on me, it's been a long time since I programmed PHP. So I guess the following code is written very quick and dirty.

First I need a method for reading the HTTP Header to check a secret that I send along with the request.

// code/upload.php#L3-L19

function getRequestHeaders() {
    $headers = array();
    foreach($_SERVER as $key => $value) {
        if (substr($key, 0, 5) <> 'HTTP_') {
        $header = str_replace(' ', '-', ucwords(str_replace('_', ' ', strtolower(substr($key, 5)))));
        $headers[$header] = $value;
    return $headers;

$headers = getRequestHeaders();

if ($headers['Secret'] !== "<your secret>") {
    die("wrong secret");

The file can be accessed with $_FILES. To store the image somewhere, use move_uploaded_file.

// code/upload.php#L21-L22

move_uploaded_file($_FILES['zip-file']['tmp_name'], './'.$_FILES['zip-file']['name']);

It is very basic but should be enough to accept files from anywhere. To speed up the upload process I moved the whole /distdirectory into a ZIP archive. So I need to unzip it with PHP:

// code/upload.php#L23-L30

$zip = new ZipArchive;
if ($zip->open('') === TRUE) {
    echo 'ok';
} else {
    echo 'error duringunzip';

Zip & send the files with NodeJS

For zipping the files I use archiver and for making the upload request request.

archiver is very straightforward and only needs a few lines of code:

// code/zip.js

var fs = require('fs');
var archiver = require('archiver');

var fileName =   ''
var fileOutput = fs.createWriteStream(fileName);
const archive = archiver('zip');

fileOutput.on('close', function () {
    console.log(archive.pointer() + ' total bytes');
    console.log('archiver has been finalized and the output file descriptor has closed.');

archive.pipe(fileOutput);'dist/', false);
archive.on('error', function(err){
    throw err;

Sending the file is also very simple and done quickly:

// code/send.js

const request = require("request");
const fs = require("fs");
const path = require("path");
var options = {
    url: '',
    headers: {
        secret: process.env.JB_UPLOAD_SECRET
var r =, function optionalCallback (err, httpResponse, body) {
  console.log('Server responded with:', body, err);
var form = r.form()
form.append('zip-file', fs.createReadStream(path.join(__dirname, "..", '')))


I replaced the FTP deployment with a HTTP upload endpoint. The /dist directory is zipped and unzipped with php. This was required because FTP upload does not work with travis very well.

Found a typo?

As I am not a native English speaker, it is very likely that you will find an error. In this case, feel free to create a pull request here: . Also please open a PR for all other kind of errors.

Do not worry about merge conflicts. I will resolve them on my own.

Discussion (0)

Editor guide