Имам проблем с функцията foreach - Illegal offset type in

Ticketa

Registered
<b>Warning</b>: Illegal offset type in <b>/home/ticketa/public_html/file.php</b> on line <b>8</b><br />

PHP:
foreach ($_POST['id'] as $value) {
	$pole[$value] = $_POST['qty'][$i]; // tova e 8 red
	$i++;
}

Това се получава, когато в полето id изпращам следните символи;

id[][$test]=1
id[]=1
qty[]=1
qty[]=1

Същия проблем се отнася и за QTY.

<input type="hidden" name="id[]" ......
<input type="hidden" name="qty[]" ......

Пробвах със htmlspecialchars да филтрирам , обаче ми връща грешка:

<b>Warning</b>: htmlspecialchars() expects parameter 1 to be string, array given in

А съм написал параметрите правилно.

Вече е прекалено късно и яко съм зациклил, а си играя от има няма 1 час точно с тая щуротия. . някой да удари едно рамо? :D :))


П.П. - Принципно в тези две полета ще се съдържат само и единствено числа (динамични)


Стигнах до следното решение, въпреки че не ми се вижда много разумно:

PHP:
foreach ($_POST['id'] as $value) {
	if(is_numeric($value)) {
		$pole[$value] = $_POST['qty'][$i];
		$i++;
	} else {
		die("NO! Manipulate detected!");
	}
}

Обаче в тоя случай QTY полето отново е уязвимо въпреки, че обхождам ВСИЧКИ _POST, _GET, _COOKIE и т.н. променливи.

Идеи?
 
Код:
foreach($_POST['id'] as $key=>$value)
{


$_POST['id'][$key] = htmlspecialchars($_POST['id'][$key], ENT_QUOTES);
}
b>Warning</b>: htmlspecialchars() expects parameter 1 to be string, array given in
Грешката , реално означава : Че метода очаква стринг, а ти му даваш масив.

is_numeric е добре, но може и по-добре.
Според примера който е даден в php.net
ако имаш " 1е4 " ще ти каже , че е сило. В математиката - може и да бъде число, но тук не е , защото "Е" е буква.
Създай си един празен файл и постави този код, ако не успяваш да ме разбереш :)


PHP:
$var  = '1e4';
if(is_numeric($var)) { echo $var ." e chislo <br/>"; } 
echo (int)$var." no tova e istinsko 4islo ";


if (is_int(23)) {
    echo "is integer<br/>";
} else {
    echo "is not an integer<br/>";
}

var_dump(is_int(23));

echo "<br/>";
var_dump(is_int("23"));

echo "<br/>";
var_dump(is_int(23.5));

echo "<br/>";
var_dump(is_int(true));
 
Не, за примера ми стана ясно. Относно is_numeric и is_int, знаех го това, но когато съм вкарал is_int ми дава FALSE при масивите. (дори да има само число)

Направил съм си примерна проверка:

PHP:
function isValid($array) {
    $valid = FALSE;
    foreach ($array as $key => $value) {
        if (is_int($array[$key])) {
            $valid = TRUE;
            break;
        }
    }
	//var_dump($valid);
    return $valid;
}

Нея е използвам така:

PHP:
if(isValid($_POST['id']) && isValid($_POST['qty'])) {
//OK
} else {
die("Problem");
}

Ако is_int ми е is_numeric - няма проблеми, но ако е INT ми прави проблеми при масивити - защо? Как ще стане правилната структура(код)?

Това ми е var_dump-а на _POST['id']

array(2) {
[0]=> string(1) "2"
[1]=> string(1) "1"
}

А това на _POST['qty']

array(2) {
[0]=> string(1) "1"
[1]=> string(1) "5"
}
 
PHP:
function isValid($array) {
    $valid = FALSE;
    foreach ($array as $key => $value) {
        if (is_int($array[$key])) {
            $valid = TRUE;
            break;
        }
    }
        //var_dump($valid);
    return $valid;
}
масив array('1','2','asd');
loop 1 $valid : true
loop 2 $valid : true
loop 3 $valid : false
Това се очаква. Но става следното :
loop 1 $valid : true : край на обхода
Според това , което виждам. Може и да е грешка.
Ето ти едно подобно решение, което аз змятам за правилно.
PHP:
function isValid($array,&$newArray=null) {
    foreach ($array as $key => $value) {
        if (is_int($array[$key])) {
            $newArray[$key] = $value;
        }/if
    }//foreach
    if(count($newArray) == 0) return false; else return $newReturn;

}//isValid

По този начин можеш да го ползва :

PHP:
$nArray = null;
if(isValid($array,$nArray)) {   var_dump($nArray); } 
// Ili 
if(isValid($array)) {   var_dump(isValid($array)); }
Този метод , който съм ти дал ще ти върне всички валидни данни , а ако няма валидна ще върне false;
Разликата между двете , е че функцията се обръща към $nArray заради & в дефеницията на метода. А другото направо ти връща резултата.

Може и да съм допуснал някоя синтактична грешка ,защото го пиша тук в форума.
 
Не, пак ми връща False.

PHP:
<?php
function isValid($array,&$newArray=null) {
    foreach ($array as $key => $value) {
        if (is_int($array[$key])) {
            $newArray[$key] = $value;
        }//if
    }//foreach
    if(count($newArray) == 0) return false; else return $newReturn;

}//isValid
$nArray = null;
$test = array('1','2', '3');
if(isValid($test)) {
	var_dump($test);
} else {
	echo "false";
}

Самия array го връща като: string(1), string(2), string(3)

Интересно, че ако го обходя с array_map няма проблеми.

Ето така кода работи;

PHP:
<?php
function isValid($array,&$newArray=null) {
    foreach ($array as $key => $value) {
        if (is_int($array[$key])) {
            $newArray[$key] = $value;
        }//if
    }//foreach
    if(count($newArray) == 0) return false; else return true;
}//isValid
$nArray = null;
$test = array('1','2','2asd');
$test = array_map('intval', $test);
if(isValid($test)) {
	echo "success";
} else {
	echo "false";
}

Като "трие" от масива asd и връща true.

Тоест само число.

Ако има ПО-ДОБРА алтернатива, от този вариант да е ползвам нея или така да го оставям?
 
Сега забелязах още един проблем.

След като оправих единия проблем с array_map, сега намерих ДРУГ..


Ако изпращащите данни изглеждат така:

act=update&qty[]=2&id[]=1&&qty[$test]=5&pid[]=2

И в полето $_POST['qty']
масива бъде променен с [$test]

тоест;
<input type="hidden" name="qty[$test]"......

Връща следния проблем:

Notice: Undefined offset: 1 in ... 14 line


PHP:
<?php
function isValid($array,&$newArray=null) {
	foreach ($array as $key => $value) {
		if (is_int($array[$key])) {
			$newArray[$key] = $value;
		}//if
	}//foreach
	if(count($newArray) == 0) return false; else return true;
}//isValid
if(isSet($_POST['id'] && isSet($_POST['qty']) && is_array($_POST['id'] && is_array($_POST['qty'])) {
$_POST['id'] = array_map('intval', $_POST['id']);
$_POST['qty'] = array_map('intval', $_POST['qty']);
if (isValid($_POST['id']) && isValid($_POST['qty'])) {
	foreach ($_POST['id'] as $value) {
		$NewInput[$value] = $_POST['qty'][$i];
		$i++;
	}
}//if two
}//if one

14 ред е: $NewPole[$value] = $_POST['qty'][$i];

Едит и с това се оправих.

PHP:
if (!empty($_POST['qty'][$i])) {
	$NewInput[$value] = $_POST['qty'][$i];
	$i++;
} else {
	die("Hacking attempt!");
}

Давам ти +1, защото се отзова и ми помогна донякъде! Мерси готин :)
 
PHP:
<?php

function isValid($array, &$newArray = null) {
    if (!is_array($array)) {
        return false;
    }
    foreach ($array as $key => $value) {
        if (is_numeric($value))
            $newArray[$key] = $value;
    }
    if(count($newArray)==0) return false; else return $newArray;
}

$test = array('1', 21, '3s');
if (!isValid($test, $nArray)) {
    echo "false";
}

var_dump($nArray);
?>
Съжелявам, моя грешка в кода :} Това вече работи на 100%
 

Back
Горе