Crie uma pasta se ela ainda não existir

641

Já deparei com alguns casos com instalações do WordPress com Bluehost, onde encontrei erros no meu tema do WordPress porque a pasta de uploads wp-content/uploadsnão estava presente.

Aparentemente, o instalador do Bluehost cPanel WordPress não cria esta pasta, embora HostGator o .

Portanto, preciso adicionar código ao meu tema que verifique a pasta e a crie de outra forma.

Scott B
fonte
7
if (!file_exists('path/to/directory')) { mkdir('path/to/directory', 0777, true); }
Eu sou a pessoa mais estúpida

Respostas:

1228

Tente isso usando o mkdir :

if (!file_exists('path/to/directory')) {
    mkdir('path/to/directory', 0777, true);
}

Observe que 0777já é o modo padrão para diretórios e ainda pode ser modificado pelo umask atual.

quiabo
fonte
11
Você perdeu a bandeira 'recursiva' - veja a resposta de Satish.
Francois Bourgeois
118
is_dir () é um pouco mais rápido que file_exists ()
pliashkou
43
@YuryPliashkou Sim, talvez, mas não funcionará se já houver um arquivo com esse nome.
Gumbo
4
pergunta aqui: então, se houvesse um arquivo chamado 'diretório' no caminho / para, is_dir retornaria true, mas file_exists retornaria false?
Igor L.
8
file_exists- Verifica se um arquivo ou diretório existe is_file- Diz se o arquivo é um arquivo comum is_dir- Diz se o arquivo é um diretório
TarranJones
137

Aqui está a peça que faltava. Você precisa passar o sinalizador 'recursivo' como terceiro argumento (boolean true) na chamada mkdir desta forma:

mkdir('path/to/directory', 0755, true);
Satish Gadhave
fonte
8
a bandeira 'recursiva' ser o argumento 3 booleantrue
ahnbizcad
66

Algo um pouco mais universal, pois isso aparece no google. Embora os detalhes sejam mais específicos, o título dessa pergunta é mais universal.

/** 
 * recursively create a long directory path
 */
function createPath($path) {
    if (is_dir($path)) return true;
    $prev_path = substr($path, 0, strrpos($path, '/', -2) + 1 );
    $return = createPath($prev_path);
    return ($return && is_writable($prev_path)) ? mkdir($path) : false;
}

Isso seguirá um caminho, possivelmente com uma longa cadeia de diretórios não criados, e continuará subindo um diretório até chegar a um diretório existente. Em seguida, ele tentará criar o próximo diretório nesse diretório e continuará até que todos os diretórios sejam criados. Retorna verdadeiro se for bem-sucedido.

Pode ser aprimorado fornecendo um nível de parada para que apenas falhe se for além da pasta do usuário ou algo assim e incluindo permissões.

phazei
fonte
@phazei Recebo uma chamada para a função indefinida por causa da linha $ return = createPath ($ prev_path);
precisa
Obrigado @phazei :)
Alex
58

Que tal uma função auxiliar como esta:

function makeDir($path)
{
     $ret = mkdir($path); // use @mkdir if you want to suppress warnings/errors
     return $ret === true || is_dir($path);
}

Ele retornará truese o diretório foi criado com sucesso ou já existe, e falsese o diretório não pôde ser criado.

Uma alternativa melhor é esta (não deve dar nenhum aviso):

function makeDir($path)
{
     return is_dir($path) || mkdir($path);
}
AndiDog
fonte
4
Se você remover o @e substituí-lo por uma is_dirverificação adequada , meu voto positivo será seu :) Pontos extras para verificar se o diretório pai is_writable()de uma função auxiliar à prova d'água.
Pekka
Usar @ para suprimir os erros é um problema de desempenho. Melhor para verificar se ainda não existir como Gumbo
Simon
1
Independentemente da supressão de erro, estou inclinado a -1 no primeiro exemplo. O segundo é muito melhor que o primeiro é inútil.
23710 Justin Justin
É difícil ler o código apenas para colocá-lo em uma linha. A resposta aceita é muito mais clara.
precisa saber é o seguinte
27

Maneira mais rápida de criar pasta:

if (!is_dir('path/to/directory')) {
    mkdir('path/to/directory', 0777, true);
}
Elyor
fonte
Isso causaria erro se houver um arquivo chamado 'diretório' nesse caminho.
Guney Ozsan
23

Crie recursivamente o caminho do diretório:

function makedirs($dirpath, $mode=0777) {
    return is_dir($dirpath) || mkdir($dirpath, $mode, true);
}

Inspirado pelo Python os.makedirs()

do utilizador
fonte
11

No WordPress, há também a função muito útil wp_mkdir_p que criará recursivamente uma estrutura de diretórios.

Fonte de referência: -

function wp_mkdir_p( $target ) {
    $wrapper = null;

    // strip the protocol
    if( wp_is_stream( $target ) ) {
        list( $wrapper, $target ) = explode( '://', $target, 2 );
    }

    // from php.net/mkdir user contributed notes
    $target = str_replace( '//', '/', $target );

    // put the wrapper back on the target
    if( $wrapper !== null ) {
        $target = $wrapper . '://' . $target;
    }

    // safe mode fails with a trailing slash under certain PHP versions.
    $target = rtrim($target, '/'); // Use rtrim() instead of untrailingslashit to avoid formatting.php dependency.
    if ( empty($target) )
        $target = '/';

    if ( file_exists( $target ) )
        return @is_dir( $target );

    // We need to find the permissions of the parent folder that exists and inherit that.
    $target_parent = dirname( $target );
    while ( '.' != $target_parent && ! is_dir( $target_parent ) ) {
        $target_parent = dirname( $target_parent );
    }

    // Get the permission bits.
    if ( $stat = @stat( $target_parent ) ) {
        $dir_perms = $stat['mode'] & 0007777;
    } else {
        $dir_perms = 0777;
    }

    if ( @mkdir( $target, $dir_perms, true ) ) {

        // If a umask is set that modifies $dir_perms, we'll have to re-set the $dir_perms correctly with chmod()
        if ( $dir_perms != ( $dir_perms & ~umask() ) ) {
            $folder_parts = explode( '/', substr( $target, strlen( $target_parent ) + 1 ) );
            for ( $i = 1; $i <= count( $folder_parts ); $i++ ) {
                @chmod( $target_parent . '/' . implode( '/', array_slice( $folder_parts, 0, $i ) ), $dir_perms );
            }
        }

        return true;
    }

    return false;
}
Trevor Mills
fonte
6

Eu preciso da mesma coisa para um site de login. Eu precisava criar um diretório com duas variáveis. O diretório $ é a pasta principal onde eu queria criar outra subpasta com o número de licença do usuário.

include_once("../include/session.php");
$lnum = $session->lnum; //Users license number from sessions
$directory = uploaded_labels; // Name of directory that folder is being created in

if (!file_exists($directory."/".$lnum)) {
mkdir($directory."/".$lnum, 0777, true);
}
Progrower
fonte
5

Esta é a solução mais atualizada sem supressão de erros:

if (!is_dir('path/to/directory')) {
    mkdir('path/to/directory');
}
Andreas
fonte
3

Se você quiser evitar o problema do file_existsVS is_dir, sugiro que você olhe aqui

Eu tentei isso e ele só cria o diretório se o diretório não existir . Não importa se existe um arquivo com esse nome.

/* Creates the directory if it does not exist */
$path_to_directory = 'path/to/directory';
if (!file_exists($path_to_directory) && !is_dir($path_to_directory)) {
    mkdir($path_to_directory, 0777, true);
}
joaorodr84
fonte
2
if (!is_dir('path_directory')) {
    @mkdir('path_directory');
}
Mayur Kukadiya
fonte
3
Supressão de erro? Por quê?
Canadiancreed
4
Com a supressão de erro, não há necessidade de verificação de que diretório existe
neoascetic
4
é melhor lidar com erros do que suprimi-los. Se isto falhar, você nunca vai saber porquê disso, e terá de pesquisá-lo
Tim Ogilvy
Em ambientes altamente simultâneos / multithread, é aconselhável suprimir o erro. Pode ocorrer uma condição de corrida na qual dois ou mais encadeamentos avaliarão is_dir () como false e tentarão criar o diretório. O primeiro thread poderá criá-lo sem nenhum problema, mas os outros threads falharão, porque o diretório já existe. Para evitar a falta de uma criação de diretório com falha, verifique a existência do diretório após a chamada para @mkdir () novamente.
tobain 27/09/17
2

Você pode tentar também:

$dirpath = "path/to/dir";
$mode = "0777";
is_dir($dirpath) || mkdir($dirpath, $mode, true);
simhumileco
fonte
2

Para criar uma pasta se ela ainda não existir

Considerando o ambiente da pergunta.

  • WordPress.
  • Servidor de hospedagem na web.
  • Supondo que seu Linux não seja Windows executando PHP.

E citando: http://php.net/manual/en/function.mkdir.php

bool mkdir (string $ nome do caminho [, int $ mode = 0777 [, bool $ recursivo = FALSO [, recurso $ contexto]]])

O manual diz que o único parâmetro necessário é o $pathname!

então, podemos simplesmente codificar:

<?php
error_reporting(0); 
if(!mkdir('wp-content/uploads')){
   // todo
}
?>

Explicação:

Não precisamos passar nenhum parâmetro ou verificar se existe uma pasta ou mesmo passar o parâmetro de modo, a menos que seja necessário; pelos seguintes motivos:

  • O comando criará a pasta com a permissão 0755 (permissão padrão da pasta de hospedagem compartilhada) ou 0777 o padrão do comando.
  • modeé ignorado no Windows Hosting executando PHP .
  • O mkdircomando já foi construído no verificador se a pasta existe; então precisamos verificar o retorno apenas True | False; e não é um erro, é apenas um aviso e o Aviso é desativado em servidores de hospedagem por padrão.
  • Conforme a velocidade, isso é mais rápido se o aviso estiver desativado.

Essa é apenas outra maneira de analisar a questão e não reivindicar uma solução melhor ou mais ideal.

Testado em PHP7, Servidor de produção, Linux

WPDev
fonte
2
$upload = wp_upload_dir();
$upload_dir = $upload['basedir'];
$upload_dir = $upload_dir . '/newfolder';
if (! is_dir($upload_dir)) {
   mkdir( $upload_dir, 0700 );
}
Nikunj Kathrotiya
fonte
2

Devemos sempre modularizar nosso código e escrevi a mesma verificação abaixo ... Primeiro, verificamos o diretório, se o diretório estiver ausente, criamos o diretório.

$boolDirPresents = $this->CheckDir($DirectoryName);

if (!$boolDirPresents) {
        $boolCreateDirectory = $this->CreateDirectory($DirectoryName);
        if ($boolCreateDirectory) {
        echo "Created successfully";
      }
  }

function CheckDir($DirName) {
    if (file_exists($DirName)) {
        echo "Dir Exists<br>";
        return true;
    } else {
        echo "Dir Not Absent<br>";
        return false;
    }
}

function CreateDirectory($DirName) {
    if (mkdir($DirName, 0777)) {
        return true;
    } else {
        return false;
    }
}
Aditya
fonte
1

Você primeiro precisa verificar se o diretório existe file_exists('path_to_directory')

Em seguida, use mkdir(path_to_directory)para criar um diretório

mkdir( string $pathname [, int $mode = 0777 [, bool $recursive = FALSE [, resource $context ]]] ) : bool

Mais sobre mkdir () aqui

Código completo aqui:

$structure = './depth1/depth2/depth3/';
if (!file_exists($structure)) {
    mkdir($structure);
}
Nasir Khan
fonte
0

Aqui está.

if (!is_dir('path/to/directory')) {
    if (!mkdir('path/to/directory', 0777, true) && !is_dir('path/to/directory')) {
        throw new \RuntimeException(sprintf('Directory "%s" was not created', 'path/to/directory'));
    }
}
ULIDU THEERAKE
fonte
O PHPStorm (com inspeções do PHP) fornece exatamente essa sugestão ;-) btw. você pode mesclar o externo se no interior: if (! is_dir (...) &&! mkdir (...) &&! is_dir (...)) ...
aProgger
-1

A resposta aceita funciona, mas não é a solução correta devido às permissões. As permissões 0777 permitem que todos acessem / leiam / gravem o diretório. Não é isso que queremos para o diretório de upload no servidor da web. Aqui está a solução correta e completa sugerida.

$path_to_directory = 'path/to/directory';
if (!file_exists($path_to_directory) && !is_dir($path_to_directory)) {
    mkdir($path_to_directory, 0644, true);
}

0644 são as permissões corretas para o diretório de uploads porque normalmente não queremos que o upload no servidor seja executado lá.

true é o terceiro parâmetro para definir a propriedade recursiva como true ou false. Permite a criação de diretórios aninhados especificados no nome do caminho.

Umair Anwar
fonte