EN
Get started

Help · Website

PHP and the data area

With the «PHP» add-on, server-side code runs on your website. It sees two directories: your published files under /var/www/html – read-only and replaced every time you publish – and the data area under /var/www/storage, where your code writes and which no publish ever touches. You read the path with getenv('PUBLISHING_STORAGE'). Files such as a configuration with an API key go into the portal, in the «Data» tab – never into the chat.

At a glance

Location What lives there Your code may
/var/www/html Your published files only read
/var/www/storage The data area: configuration, orders, uploads read and write
/var/www/storage/sessions Your visitors' sessions – PHP manages them itself leave alone
/var/www/tmp Uploads while the request is running store nothing of its own
/tmp Scratch space, 64 MB, gone after every pause only short-lived things

A path outside these four aborts with a message about open_basedir. That is not a bug in your code, it is the boundary.

In the preview, PHP runs for everyone. Publishing it requires the add-on.

Two directories – and why

Your files – everything your assistant builds – are the published state. They are replaced completely every time you publish, and while the website is running it cannot change them. That is deliberate: what gets served should not be able to rewrite itself. It is exactly what stops the most common form of infestation after a security hole – whoever finds a hole cannot leave behind a file that runs along with the next visitor.

The data area sits next to it. That is where your PHP writes, and publishing never touches it. It cannot be reached from the web: whatever is in it, your website serves itself – with its own check of who is allowed to see it. An uploaded .php is never executed there either.

Addressing the data area in PHP

The path is in the environment variable PUBLISHING_STORAGE. Take it from there instead of hard-coding it:

<?php
$data = getenv('PUBLISHING_STORAGE') ?: '/var/www/storage';

file_put_contents($data . '/orders.csv', $line, FILE_APPEND | LOCK_EX);

getenv() and not $_ENV: there is nothing in $_ENV here, PHP does not fill it in this setup.

Two more variables help you:

  • PUBLISHING_VORSCHAU is 1 when the code runs in the preview, and absent otherwise. That way your website can use, say, a test key of a payment API in the preview.
  • PUBLISHING_HOSTING is always 1 – it tells your code that it runs with us and not on your computer.

Putting files in: the «Data» tab

Your website's workspace has a «Data» tab. There you upload, create folders, download and delete – for example the configuration file your code reads its API key from. There is no predefined one: the data area starts empty, and your code decides what the file is called and what is in it.

How to go about it:

  1. Ask your assistant which file the code expects and what goes into it – with placeholders instead of real values.
  2. Create the file on your computer and enter the real values there.
  3. Open the «Data» tab, choose Live or Preview at the top and upload the file.
  4. Open the page that needs the file. Check in the preview first – that is where you see error messages.

And do it there, not in the chat. Such files hold keys and passwords, and those should not pass through a language model. Your assistant deliberately has no tool for the data area; it can tell you what belongs in there, but you put it there yourself. We do not offer FTP.

What the tab can and cannot do:

  • A single file may be up to 100 MB.
  • A folder can only be deleted when it is empty – a slip of the mouse should not take a whole tree with it.
  • There are no versions. What you delete or overwrite here is gone. Unlike your website files, your assistant cannot bring anything back.
  • The sessions folder belongs to PHP and is not shown.
  • A name may not end in a dot or a space, may be at most 120 characters long and may not sit deeper than ten folders. .. is not allowed.
  • A leading dot stays: .env is still called .env after uploading.

Live and preview

The preview has its own data area, separate from that of the published website. Someone looking at a new version of their order handling should not overwrite the real orders along the way. The switch at the top of the «Data» tab moves between the two.

  • The preview area starts out empty. If your code needs a configuration to start, you have to put one there as well. That is the most common reason why something works live but not in the preview.
  • It persists across several previews and pauses. It is deleted when the website no longer runs on MADLAB hosting.
  • Both areas together count against your plan's space.

What works

  • Sessions. A login stays signed in, even across a pause of the website.
  • Uploads by your visitors up to 100 MB per file and up to 20 files in one request.
  • Services on the internet over HTTPS: payment APIs, map services, newsletter providers.
  • Mail via SMTP with a mail provider, on port 587 or 465. See below about mail().
  • SQLite as a database in a file in the data area.
  • .htaccess applies fully: redirects, headers, php_value.
  • PHP 8.4 with the common extensions, including curl, mbstring, openssl, sodium, gd, intl, zip, exif, pdo_sqlite and sqlite3.
  • Time zone Europe/Zurich, character set UTF-8.

What does not work

  • mail() sends nothing. It returns false, live and in the preview. For contact forms, use SMTP with a mail provider – mail also arrives more reliably that way, because the provider handles sender verification (SPF, DKIM) for you.
  • No database server. We have no MySQL, and you cannot reach a database elsewhere either: the way out is only open on ports 80, 443, 587 and 465, and MySQL needs 3306. Use SQLite, or a service that offers an API over HTTPS.
  • Nothing executed. exec, shell_exec, system and their relatives are disabled. There is no command line and no Composer on the server.
  • Nothing that runs on a schedule. There is no cron. Anything that should happen on a schedule has to be done as part of a page request.
  • No services of your own, no open ports, no connections into private networks.
  • No writing into your own files. /var/www/html is read-only.

Files with these endings are never served, even if you wanted to allow it in an .htaccess: .env, .ini, .log, .sql, .bak, .swp, .git, composer.json, composer.lock, and anything starting with a dot (except .well-known). That is a second safeguard – the first is not to have such files among your website files at all.

Limits in numbers

What Limit
Data area, live and preview together 500 MB in the «MADLAB hosting» plan
One file in the «Data» tab 100 MB
A visitor's upload 100 MB per file, 20 files, 110 MB per request
Memory per request 128 MB
Run time per request 30 seconds
Simultaneous requests 8
Pause after 15 minutes without a visit (preview: 10)

After a pause, the first request takes a little longer because the website has to start. Sessions and the data area survive that; whatever was in /tmp does not.

Error messages

The preview shows error messages. On the published page they stay hidden, so that no paths and queries end up in front of visitors – live you see a blank page or a generic error page. So always use the preview for troubleshooting. A log of the published website is not available to you; if you need one, write it yourself into the data area (see best practices).

Backup

The data area is not backed up – neither live nor preview. Your website files are versioned and can be brought back; what your PHP writes into the data area cannot. So download important data such as orders regularly in the «Data» tab, or give your website an export function.

How to build a PHP website that is secure, robust and easy to maintain is covered in the best practices for PHP websites.

Didn’t that help? hallo@madpublishing.ch