Confirming the presence/create directories While preparing an automated process to manipulate files, I've made the following function to check for the base directory and sub-directories presence, as to allow or deny the remaining code to be executed:

/* Check Directories
 *
 * Confirm that the necessary directories exist, and if not,
 * tries to create them.
 *
 * @_param string $whereAmI    -&gt; Script location
 * @_param string $backup_path -&gt; target directory relative path
 * @_param array  $subDirArr   -&gt; sub-directories array
 *
 * @return 
 *  success -&gt; Boolean
 *  failure -&gt; string with failure path
 */
function check_directories($whereAmI, $backup_path, $subDirArr) {

  // initialize return variable
  $status = FALSE;

  // check for the merchant base directory
  if (!is_dir($whereAmI."/".$backup_path)) {

      // trying to create the directory with permissions
      exec("mkdir ".$backup_path." -m 777 2&gt;&amp;1", $output, $return_value);

      // error returned, stop and return status
      $status = (is_array($output) &amp;&amp; count($output)&gt;=1) ? $backup_path : TRUE;
  } else {
    $status = TRUE;
  }

  // base directory exists, continue
  if ($status===TRUE) {

      // run by each sub-directory
      foreach ($subDirArr as $subDir) {

          /* keep checking for status value, if changed,
           * one directory has failed and we can't proceed
           */
          if ($status===TRUE) {

              // check for the sub-directory presence
              if (!is_dir($whereAmI."/".$subDir)) {

                  // trying to create the directory with permissions
                  exec("mkdir ".$subDir." -m 777 2&gt;&amp;1", $output, $return_value);

                  // error returned, stop and update status
                  $status = (is_array($output) &amp;&amp; count($output)&gt;=1) ? $subDir : TRUE;
              }

          } else {
              return $status;
          }
      }
  }

  return $status;
}


Considerations:


Directory permissions when in production aren't 777.
Server is running PHP Version 5.3.10.


Can this be simplified, thus reducing the amount of code, and perhaps in such reduction, have it improved?
Quite a few things wrong with your PHPDoc. I'm actually learning quite a bit myself. Doccomments require two asterisks to begin, not one, no matter what language you are using. One asterisk just defines a multi-line comment. Your IDE will skip over this, essentially making these useless as doccomments. The underscore before param, the "yields" operator -&gt;, and your return syntax all cause my IDE to ignore this comment because it is in the wrong syntax. The multi-return sequences are best done using the bitwise OR operator separating the types, but you can also use a "mixed" type to accomplish the same thing.

/** Check Directories
  * etc...
  * @param string $whereAmI Script location
  * @return bool|string String on success, FALSE on failure
//OR
  * @return mixed String on success, FALSE on failure
  */


Be careful with "clever" variables. For a few seconds there I was quite confused about your $whereAmI variable, thinking that last letter was an "L" and not an "I". I'm a bit slow sometimes and I was sitting there scratching my head trying to figure out what an "aml" was (in case you're curious, my best guess was animal). I would stick with simple variable names, such as $location or $position. Additionally, pick a style and be consistent. I see both camelCase AND under_score variables. One or the other, not both. You can do one for functions and the other for variables, if you wish. I've seen that done frequently enough that I wouldn't comment on it, but switching between the styles on the same datatype is just confusing.

Internal comments, especially ones that explain what is already in the doccomments, are just noise. Anyone reading this function will know that $status is important, and once they reach the end of the function they will know its also returned. If, like me, you skip to the bottom of the function to see what it returns and then work backwards from there, then you will already know that it is returned. Same for the rest of these comments. The only time I use internal comments is for explaining confusing lines, such as REGEX, compact(), extract(), or, in your case, that exec().

Alright, lets move on to actual code.

Why did you bother setting an initial value to $status, your very next line of code overwrites that value no matter what. Let the if/else statements assign it for you. Or lose the else and use that as the default value.

Avoid using "not" ! unless you have to. In this instance you have an if/else statement. Switch them around and remove the "not". In the above scenario you would keep the "not".

if( is_dir( $whereAmI . '/' . $backup_path ) ) {
    $status TRUE;
} else {


Explaining Not:

If you are doing a single if statement, then the not is fine and necessary. Though this could be argued that the empty() function should be used, either is fine, but I find the "not" syntax preferrable in this case.

if( ! $var ) {//fine
//OR
if( empty( $var ) ) {//also fine, though less preferrable IMO


If you are using an if/else statement, as I demonstrated in initial answer, the not is implied by else and should be removed for clarity as well as efficiency.

if( $var ) {
} else {//not implied here
}


This helps with clarity because the "not" operator ! is not always immediately noticeable, depending on how you space your statements (which is one of the reasons my statements are so spacious). This helps with efficiency because typically your "not" clause holds the least amount of coding and might even contain an early escape, resulting in the else syntax not even being necessary which meaning less indentation and increased clarity.

if( $var ) {
    return FALSE;
}
//contents of else


The only time to compare a value explicitly to a boolean is when doing a type comparison. Such as an integer "0" to a boolean "FALSE", or string "FALSE" to FALSE. And the above rules hold true for this as well.

if( $var !== FALSE ) {
//OR
if( $var === FALSE ) {
} else {
}
//OR
if( $var === FALSE ) {
    return FALSE;
}
//contents of else


End of Explanation

You mentioned security; You should be careful of functions such as exec(). Functions, by definition, are public. So, this script is public, therefore you can not guarantee the validity of those parameters being passed to it, or rather, you aren't validating them. This is a potential security issue, but only if you plan on using this in a public domain (internet). That and the "777" permissions. Directories should not be executable. I can't remember off the top of my head what the proper permissions to use are, but I DO know that "777" will get you in trouble. Though, admittedly I do this in my server as well, but mine is a small intranet and security isn't one of the things I'm particularly worried about.

Split up your function. It is concerned with entirely too much. check_directories() should only be concerned with checking the directories, but then you start adding on subdirectories. This is a different concern altogether. Take a look at the Single Responsibility Principle. Additionally, look at "Don't Repeat Yourself" (DRY) Principle. Your if/else statement that I mentioned above is repeated, therefore it can be made into a function to avoid this. This will be the biggest contributor to reducing the size of this program. That and removing those unnecessary comments. Besides that, I don't think there are any other ways to do this.