Basic login script for educational purposes
First, all of your indentation is half indentation: you two-spaces instead of four.

Most IDEs have proper spacing if you press TAB.



Naming:

You have variables need re-naming:


$_SESSION['log']: a log is a regular or systematic record of incidents or observations, not whether you've logged in, which has entirely different meaning, also the same applies to the following variables, log is a completely different thing than the state it represents: loggedIn or signedIn would be much better.
$pass, $_SESSION['pass'], $user and $_SESSION['user']: it's really not worth it to sacrifice four extra characters here and there, for the sake of simplification. add word and name to the end of those.




Security:

You SHOULD not be saving the password to a session variable, there are ways to break into sessions, and therefore, is an insecure way to save them longer than needed; use unset($_SESSION['password']) to remove them after processing.



Failed Globals:

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
        $errors = array();


You use the $errors variable outside of the if statement, which is a no-no. Declare the variable up there with session_start().



You shouldn't be manually providing the name of the PHP form, but, rather using $_SERVER['PHP_SELF'] instead:


&lt;form method="post"&gt;



into:

&lt;form action=&lt;?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?&gt; method="post"&gt;





  if (count($errors) &gt; 0) {
    foreach($errors as $e) {
      echo $e . '&lt;br&gt;';
    }
  }




count($errors) &gt; 0 can be simplified to: count($errors)
count($errors) can simplified to: $errors
$errors can simplified to: '' (Nothing)


Explicitly checking the length of $errors is redundant, when you have a for or foreach loop.

If there's \$0\$ elements, the foreach won't trigger.

foreach($errors as $e) {
    echo $e . '&lt;br&gt;';
}


In fact, in this instance, foreach is redundant in itself.

Using a neat function called implode, you can join an array together, without needing to iterate over its elements explicitly.

echo implode('&lt;br&gt;', $errors);


Actually, &lt;br&gt; isn't really the best way to display multiple errors.

Consider using &lt;ul&gt; instead.

&lt;ul&gt;
    &lt;li&gt;
    &lt;?php echo implode ('&lt;/li&gt;&lt;li&gt;', $errors); ?&gt;
    &lt;/li&gt;
&lt;/ul&gt;


That certainly slimmed down, didn't it? When displaying content built from variables or arrays, make sure you consider how you choose to return them to the client.




    &lt;ol&gt;
      &lt;li&gt;
        &lt;label for="user"&gt;Username&lt;/label&gt;
        &lt;input name="user" type="text"&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;label for="pass"&gt;Password&lt;/label&gt;
        &lt;input name="pass" type="password"&gt;
      &lt;/li&gt;
    &lt;/ol&gt;



A few points to make about this block:


Why are you using &lt;ol&gt;? It seems silly, and pointless. Even using &lt;ul&gt; would be pointless.
In the &lt;input&gt; you can use the attribute placeholder, which as the name suggests, lets you set a placeholder to show an example password, or the name of the field. Personally, I'd ditch the labels, and put username and password as placeholders. As @KevinBrown pointed out in the comments: screen readers need lables, and without them, it can cause issues, however, I'd still set placeholders.

&lt;ol&gt;
  &lt;li&gt;
    &lt;label for="user"&gt;Username&lt;/label&gt;
    &lt;input name="user" type="text"&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;label for="pass"&gt;Password&lt;/label&gt;
    &lt;input name="pass" type="password"&gt;
  &lt;/li&gt;
&lt;/ol&gt;



Into:

&lt;input name="user" placeholder="username" type="text"&gt;
&lt;input name="pass" placeholder="password" type="password"&gt;


You can individually space them with CSS (Recommended method), &lt;ul&gt; + inline, or &lt;br&gt;.




if (isset($_SESSION['log']) &amp;&amp; !empty($_SESSION['log'])) {



$_SESSION['log'] is stored as a boolean, not a variable. Meaning, you can simply test it, without the need for functions like isset and !empty.

if ($_SESSION['loggedIn']){




Finally, the usage of $errors is a little superfluous.

$errors is used as an array, implying multiple errors will be added. However, only one $error should be added to the array, meaning a variable would be better.

Well, that would be the case, if you added a break, or return in the empty() check, but instead, you check if it's empty, add an error.

Then proceed to run through the rest of the code before comparing them. You already know if they're empty, they won't match the username and password given by the server, so why continue the script?

First, initialise $error (Note the lack of s) as a variable.
Then, break the function if they're empty.
Finally, return $error as a variable.

(I do realise this nullifies my previous point about displaying the errors, but, nonetheless, if you were to display errors, that's the way to do it.)