Há muitas razões pelas quais se pode encontrar esse erro e, portanto, uma boa lista de verificação do que verificar primeiro ajuda consideravelmente.
Vamos considerar que estamos solucionando problemas da seguinte linha:
require "/path/to/file"
Lista de controle
1. Verifique o caminho do arquivo para erros de digitação
- verifique manualmente (verificando visualmente o caminho)
ou mova o que for chamado por require*
ou include*
para sua própria variável, faça eco, copie-o e tente acessá-lo a partir de um terminal:
$path = "/path/to/file";
echo "Path : $path";
require "$path";
Então, em um terminal:
cat <file path pasted>
2. Verifique se o caminho do arquivo está correto em relação às considerações sobre o caminho relativo versus o absoluto
- se estiver iniciando por uma barra "/", não se refere à raiz da pasta do seu site (a raiz do documento), mas à raiz do seu servidor.
- por exemplo, o diretório do seu site pode ser
/users/tony/htdocs
- se não estiver iniciando por uma barra, está contando com o caminho de inclusão (veja abaixo) ou o caminho é relativo. Se for relativo, o PHP calculará relativamente ao caminho do diretório de trabalho atual .
- portanto, não é relativo ao caminho da raiz do seu site ou ao arquivo em que você está digitando
- por esse motivo, sempre use caminhos de arquivo absolutos
Melhores Práticas :
Para tornar seu script robusto, caso você mova as coisas, enquanto ainda gera um caminho absoluto em tempo de execução, você tem 2 opções:
- use
require __DIR__ . "/relative/path/from/current/file"
. A __DIR__
constante mágica retorna o diretório do arquivo atual.
defina uma SITE_ROOT
constante você mesmo:
- na raiz do diretório do seu site, crie um arquivo, por exemplo
config.php
em config.php
, write
define('SITE_ROOT', __DIR__);
em todos os arquivos nos quais você deseja referenciar a pasta raiz do site, inclua config.php
e use a SITE_ROOT
constante onde quiser:
require_once __DIR__."/../config.php";
...
require_once SITE_ROOT."/other/file.php";
Essas 2 práticas também tornam seu aplicativo mais portátil porque não depende de configurações ini, como o caminho de inclusão.
3. Verifique seu caminho de inclusão
Outra maneira de incluir arquivos, nem de maneira relativamente nem puramente absoluta, é confiar no caminho de inclusão . Geralmente é o caso de bibliotecas ou estruturas, como a estrutura Zend.
Essa inclusão terá a seguinte aparência:
include "Zend/Mail/Protocol/Imap.php"
Nesse caso, você deve certificar-se de que a pasta onde está o "Zend" faça parte do caminho de inclusão.
Você pode verificar o caminho de inclusão com:
echo get_include_path();
Você pode adicionar uma pasta a ela com:
set_include_path(get_include_path().":"."/path/to/new/folder");
4. Verifique se o seu servidor tem acesso a esse arquivo
Pode ser que, juntos, o usuário executando o processo do servidor (Apache ou PHP) simplesmente não tenha permissão para ler ou gravar nesse arquivo.
Para verificar em qual usuário o servidor está executando, você pode usar posix_getpwuid :
$user = posix_getpwuid(posix_geteuid());
var_dump($user);
Para descobrir as permissões no arquivo, digite o seguinte comando no terminal:
ls -l <path/to/file>
e veja a notação simbólica de permissão
5. Verifique as configurações do PHP
Se nenhuma das opções acima funcionou, provavelmente o problema é que algumas configurações do PHP proíbem o acesso a esse arquivo.
Três configurações podem ser relevantes:
- open_basedir
- Se isso estiver definido, o PHP não poderá acessar nenhum arquivo fora do diretório especificado (nem mesmo através de um link simbólico).
- No entanto, o comportamento padrão é que não seja definido e, nesse caso, não há restrição
- Isso pode ser verificado ligando
phpinfo()
ou usandoini_get("open_basedir")
- Você pode alterar a configuração editando o arquivo php.ini ou o arquivo httpd.conf
- modo de segurança
- se estiver ativado, podem ser aplicadas restrições. No entanto, isso foi removido no PHP 5.4. Se você ainda está em uma versão que suporta o modo de segurança, atualize para uma versão PHP que ainda está sendo suportada .
- allow_url_fopen e allow_url_include
- isso se aplica apenas à inclusão ou abertura de arquivos por meio de um processo de rede, como http: //, não ao tentar incluir arquivos no sistema de arquivos local
- isso pode ser verificado
ini_get("allow_url_include")
e definido comini_set("allow_url_include", "1")
Caixas de canto
Se nenhuma das opções acima estiver ativada para diagnosticar o problema, aqui estão algumas situações especiais que podem ocorrer:
1. A inclusão de biblioteca que se baseia no caminho de inclusão
Pode acontecer que você inclua uma biblioteca, por exemplo, a estrutura do Zend, usando um caminho relativo ou absoluto. Por exemplo :
require "/usr/share/php/libzend-framework-php/Zend/Mail/Protocol/Imap.php"
Mas você ainda recebe o mesmo tipo de erro.
Isso pode acontecer porque o arquivo que você incluiu (com êxito), possui uma instrução de inclusão para outro arquivo, e a segunda instrução de inclusão assume que você adicionou o caminho dessa biblioteca ao caminho de inclusão.
Por exemplo, o arquivo de estrutura do Zend mencionado anteriormente pode ter o seguinte:
include "Zend/Mail/Protocol/Exception.php"
que não é uma inclusão por caminho relativo, nem por caminho absoluto. Supõe-se que o diretório da estrutura do Zend tenha sido adicionado ao caminho de inclusão.
Nesse caso, a única solução prática é adicionar o diretório ao seu caminho de inclusão.
2. SELinux
Se você estiver executando o Linux com segurança avançada, pode ser o motivo do problema, negando o acesso ao arquivo do servidor.
Para verificar se o SELinux está ativado no seu sistema, execute o sestatus
comando em um terminal. Se o comando não existir, o SELinux não estará no seu sistema. Se existir, deve informar se é aplicado ou não.
Para verificar se as políticas do SELinux são o motivo do problema, tente desativá-lo temporariamente. No entanto, tenha cuidado, pois isso desativará completamente a proteção. Não faça isso no seu servidor de produção.
setenforce 0
Se você não tiver mais o problema com o SELinux desativado, essa é a causa raiz.
Para resolvê-lo , você precisará configurar o SELinux de acordo.
Os seguintes tipos de contexto serão necessários:
httpd_sys_content_t
para arquivos que você deseja que seu servidor possa ler
httpd_sys_rw_content_t
para arquivos nos quais você deseja acesso de leitura e gravação
httpd_log_t
para arquivos de log
httpd_cache_t
para o diretório de cache
Por exemplo, para atribuir o httpd_sys_content_t
tipo de contexto ao diretório raiz do site, execute:
semanage fcontext -a -t httpd_sys_content_t "/path/to/root(/.*)?"
restorecon -Rv /path/to/root
Se o seu arquivo estiver em um diretório inicial, você também precisará ativar o httpd_enable_homedirs
booleano:
setsebool -P httpd_enable_homedirs 1
De qualquer forma, pode haver vários motivos pelos quais o SELinux negaria o acesso a um arquivo, dependendo de suas políticas. Então, você precisará investigar isso. Aqui está um tutorial especificamente sobre a configuração do SELinux para um servidor da web.
3. Symfony
Se você estiver usando o Symfony e tiver esse erro ao fazer o upload para um servidor, pode ser que o cache do aplicativo não tenha sido redefinido, porque app/cache
foi feito o upload ou esse cache não foi limpo.
Você pode testar e corrigir isso executando o seguinte comando do console:
cache:clear
4. Caracteres não ACSII dentro do arquivo Zip
Aparentemente, esse erro pode ocorrer também ao chamar zip->close()
quando alguns arquivos dentro do zip têm caracteres não ASCII em seus nomes de arquivo, como "é".
Uma solução potencial é envolver o nome do arquivo utf8_decode()
antes de criar o arquivo de destino.
Créditos a Fran Cano por identificar e sugerir uma solução para esse problema