<?php require $_SERVER['DOCUMENT_ROOT'].'/code-examples/head.php'?>
<title>File Upload</title>
</head>
<body>
  <div class="content">
    <nav><a href="/code-examples/">HOME</a></nav>
    <h1>Testing file Upload</h1>
    <h2>Explanation</h2>
    <p>
      The source code for this file is availabe at <a href="index-source.php">index-source.php</a>. That file only contains: <em>&lt;?php highlight_file("index.php"); ?&gt;</em>
    </p>
    <p>
      I am trying to upload files selected by the user of an HTML form to a directory called <em>/srv/yoursite.co.uk/public/htdocs/code-examples/file-upload/media/files/</em> on my Bytemark server.
    </p>
    <p>
      This web page including the  HTML form and the PHP code for uploading the file are in <em>index.php</em> which is in the <em>file-upload/</em> directory shown in the path above.
    </p>
    <h3>Changing Permissions on <em>files/</em></h3>
    <p>
      Before I changed any ownerships or permissions on the server, files failed to upload. I ran the command <em>chmod 777 files</em> so that <em>ls -l</em> gives: <em>drwxrwsrwx 2 admin admin 4096 Jun 23 13:09 files</em> and now files do upload to <em>files/</em>.
    </p>
    <p>
      Although this now means I can upload files to <em>files/</em> I am concerned that the permissions on the <em>files</em> directory might cause issues eg security etc.
    </p>
    <p>
      I tried making the permissions on <em>file/</em> more restrictive but only 777 works:<br>
      drwxrwsrwx works<br>
      drwxrwsr-x fails<br>
      drwxr-srwx fails<br>
      drwxr-sr-x fails (this is the standard setting for files)
    </p>
    <p>
      It appears that BOTH <em>group</em> AND <em>others</em> have to be given write access to <em>files/</em> in order for files to be uploaded.
    <p>
      It is notable that only the permissions on the <em>files/</em> needed to be changed in order to enable file uploads to it. The directories it is in (ie. <em>media/</em>, <em>file-upload/</em> and <em>code-examples/</em> did not need to be changed at all.
    </p>
    <h3>Changing Ownership of <em>files/</em></h3>
    <p>
      Taken from a random page on the internet but probably true: "<em>www-data</em> is the user that web servers on Ubuntu (Apache, nginx, for example) use by default for normal operation". You can check what user your server is running as with &lt;?php echo `whoami` ?&gt;
    </p>
    <p>
      I restored the permissions on files to their default setting and then ran <em>chown www-data:www-data files</em>. The results of that and some other owner settings are shown below:<br>
      <em>drwxr-sr-x 2 admin admin 4096 Jun 24 12:17 files/</em> fails (default)<br>
      <em>drwxr-sr-x 2 www-data www-data 4096 Jun 24 12:17 files/</em> works<br>
      <em>drwxr-sr-x 2 admin www-data 4096 Jun 24 11:59 files/</em> fails<br>
      <em>drwxr-sr-x 2 www-data admin 4096 Jun 24 11:59 files/</em> works<br>
      So, only the owner of <em>files/</em> has to be changed to <em>www-data</em> in order for files to be uploaded.
    </p>
    <h4>Problems with Normal Workflow</h4>
    <p>
      With <em>www-data</em> as the owner of <em>files/</em>, file uploads worked without changing the standard permissions of any directories. Changed ownership of <em>files/</em> also results in it being impossible to download files from <em>files/</em> using FileZilla. Hopefully this and potentially other changes in behaviour of the <em>files/</em> directory will not interrupt my normal work flow excessively. I can perform operations on the <em>files/</em> directory using SSH and then using <em>sudo</em>.
    </p>
    <h2>Test the File Upload</h2>
    <p>
      After uploading a file you need to test to see if a file has been uploaded. FileZilla can be used to see if <em>file.ext</em> has appeared in <em>files/</em>. If it has then it should be deleted so further tests can be run. If you upload an image file you should see it displayed below after submitting the form which also indicates it has been uploaded.
    </p>
    <fieldset>
      <form method="post" enctype="multipart/form-data">
      <label>File to Upload:
        <input type="file" name="my-file">
      </label>
      <input type="submit" value="submit">
    </fieldset>
      </form>
    <?php
      
if($_SERVER['REQUEST_METHOD'] == 'POST'){
        echo 
"<h3>Intermediary Output from PHP file upload code:</h3>";
        
$originalName $_FILES['my-file']['name'];
        echo 
"<p>orginalName: ".$originalName."</p>";
        
$fileTmpName $_FILES['my-file']['tmp_name'];
        echo 
"<p>fileTmpName: ".$fileTmpName."</p>";
        
$fileExtension pathinfo($_FILES['my-file']['name'], PATHINFO_EXTENSION);
        echo 
"<p>fileExtension: ".$fileExtension."</p>";
        
$newFileName "file.".$fileExtension;
        echo 
"<p>newFileName: ".$newFileName."</p>";
        
$pathToNewFile "media/files/".$newFileName;
        echo 
"<p>pathToNewFile: ".$pathToNewFile."</p>";
        
move_uploaded_file($fileTmpName$pathToNewFile);
        echo 
"<p>&lt;img style='width:15%' src='media/files/".$newFileName."'&gt;:";
        echo 
"<img style='width:15%' src='media/files/".$newFileName."'>";
      }
    
?>
  </div>
</body>
</html>