У меня есть PHP 5.6.10 под MAMP на моем локальном сервере тестирования, и этот класс работает нормально. Но когда я загружаю его на сервер веб-хостинга с PHP 5.6.31, он отображает следующую ошибку:
Warning: Invalid argument supplied for foreach() in /.../_amb.php on line 79
Класс (_amb.php) предназначен для создания простого объекта с данными и некоторыми функциями среды (пути по умолчанию, URL-адреса и т. Д.). Давайте посмотрим на класс …
// Ambiente do sistema
class _amb {
var $erro = FALSE; // Boolean FALSE | String
var $msg = "";
var $descr = "Indefinido...";
// String
var $host;
var $protocolo;
// String
var $dir;
var $dirBibPhp;
var $dirBibJs;
var $dirJGp;
var $url;
var $urlBibPhp;
var $urlBibJs;
var $urlJGp;
var $Hosts = [];
var $HostsPerms = FALSE; // Boolean FALSE | Array
var $HostsIni = ["localhost"=>[
"descr"=>"Servidor de testes local",
"dir"=>'/Applications/MAMP/htdocs/js_bib/',
"dirBibPhp"=>'/Applications/MAMP/htdocs/php_bib/',
"dirBibJs"=>'/Applications/MAMP/htdocs/js_bib/',
"dirJGp"=>'/Applications/MAMP/htdocs/jGp/',
"url"=>'{protocolo}://{host}/js_bub/',
"urlBibPhp"=>'{protocolo}://{host}/php_bib/',
"urlBibJs"=>'{protocolo}://{host}/js_bib/',
"urlJGp"=>'{protocolo}://{host}/jGp/'
]];
public function _amb($XtraHosts=FALSE, $HostsPerimitidos=FALSE){
$this->host = $_SERVER["HTTP_HOST"];
$P = explode("/", $_SERVER["SERVER_PROTOCOL"]);
$this->protocolo = $P[0];
$this->Hosts = $this->HostsIni;
if($HostsPerimitidos) $this->HostsPerms = (gettype($HostsPermitidos)=="string")? explode(",", $HostsPerimitidos) : $HostsPermitidos ;
if($XtraHosts) {
$this->import($XtraHosts);
} else {
$this->def();
}
}
private function def(){
$teste = (gettype($this->HostsPerms)=="array")? in_array($this->host, $this->HostsPerms) : TRUE ;
if(!$teste){
$this->reset();
$this->erro = "não permitido";
$this->msg = "Host ".$this->host." não permitido.";
} else {
$Defs = $this->Hosts[$this->host];
if(gettype($Defs)!="array"){
$this->reset();
$this->erro = "não identificado";
$this->msg = "Host ".$this->host." não identificado.";
} else {
foreach($Defs as $var=>$val){
$v = $val;
$v = str_replace("{raiz}", getcwd(), $v);
$v = str_replace("{protocolo}", $this->protocolo, $v);
$v = str_replace("{host}", $this->host, $v);
$this->$var = $v;
}
$this->erro = FALSE;
$this->msg = "";
}
}
}
private function reset(){
foreach($this->HostsIni[0] as $var=>$val){ //<--line 79
$this->$var = NULL;
}
}
public function isMobile() {
return (bool)preg_match('#\b(ip(hone|od)|android\b.+\bmobile|opera m(ob|in)i|windows (phone|ce)|blackberry'.
'|s(ymbian|eries60|amsung)|p(alm|rofile/midp|laystation portable)|nokia|fennec|htc[\-_]'.
'|up\.browser|[1-4][0-9]{2}x[1-4][0-9]{2})\b#i', $_SERVER['HTTP_USER_AGENT'] );
}
public function export($saida="json"){
$Def = [
"erro"=>$this->erro,
"msg"=>$this->msg,
"descr"=>$this->descr,
"dir"=>$this->dir,
"dirBibPhp"=>$this->dirBibPhp,
"dirBibJs"=>$this->dirBibJs,
"dirJGp"=>$this->dirJGp,
"url"=>$this->url,
"urlBibPhp"=>$this->urlBibPhp,
"urlBibJs"=>$this->urlBibJs,
"urlJGp"=>$this->urlJGp
];
switch($saida){
case "json":
return json_encode((object)$Def);
break;
case "html":
$html = '<table>';
foreach($Def as $var=>$val){
$html .= '<tr><td>'.$var.'</td><td>'.$val.'</td></tr>';
}
$html .= '</table>';
return $html;
break;
case "array":
return $Def;
break;
}
}
public function import($Hosts){
switch(gettype($Hosts)){
case "array":
$this->Hosts = array_merge($this->Hosts, $Hosts);
$this->def();
break;
case "string":
break;
default:
$this->reset();
$this->erro = "Hosts";
$this->msg = "Argumento inválido para ::import (".gettype($Hosts).")";
}
}
}
?>
Строка 79 — это «foreach» метода сброса (частная функция reset ()), простая процедура для очистки данных. Класс работает нормально, сайт работает, несмотря на сообщение об ошибке. Это может быть ошибка контекста, Массив не найден, но в моем локальном MAMP PHP действительно его находит.
Не могу понять, почему это работает в моей записной книжке, а не в веб-хостинга. Есть ли разница, которую я не знаю между этими версиями PHP?
Вы, вероятно, не получите сообщение об ошибке, потому что уровень ошибки отличается на веб-хосте, и предупреждение игнорируется, а у вас на сервере уровень отчетов об ошибках ниже, поэтому вы получаете это. Проблема в том, что у вас нет элемента с ключом 0 в вашем массиве, как я вижу. Вы должны сделать что-то вроде этого:
private function reset(){
foreach($this->HostsIni as $host=>$arr){
foreach($arr as $var=>$val){ //<--line 79
$this->$var = NULL;
}
}
}
Других решений пока нет …