@Denis9999

Как правильно работать с массивами?

Дали тестовое задание на собеседовании на должность php-программиста, суть которого заключалась в генерировании формы из массива. Отказали, так как очень не понравилась работа с массивом, сказали что часто надо будет работать с вложенными массивами, а читабельность моего кода не очень.
Вот картинка на которой отмечено где не так, может подскажете еще почему не так?
https://cloud.mail.ru/public/37R5FjYaRgJW/img-2015...

Весь код:
<?php 
function show_form() 
{

$arFields = array(
	'EMAIL' => array(
		'name' => 'Email',
		'validate' => 'email, length', 
		'type' => 'text', 
		'error' => 'Email не введен либо введен неверно'
	),
	'NAME' => array(
		'name' => 'Имя',
		'validate' => 'length', 
		'type' => 'text', 
		'error' => 'Введите имя'
	),
	'MESSAGE' => array(
		'name' => 'Сообщение',
		'validate' => 'length', 
		'type' => 'textarea', 
		'error' => 'Введите сообщение'
	),
);

?> 
<form action="" method=post> 
<div align="left">
    
    <?php 
	foreach ($arFields as $key => $value) {
	?>
	<br><?php echo $arFields[$key]['name']; ?><br>
	<?php if ($arFields[$key]['type'] == 'text' ) 
	{echo '<input size="40" type=' . $arFields[$key]['type'] . ' name=' . $key . ' value ="' . $_POST[$key] . '" > ';}
	else 
	{echo '<textarea rows="10" cols="35" name="' . $key . '"  >' . $_POST[$key] . '</textarea>';}
	?>

	<?php	
    } 
	?>
	
	<br><br><input type="submit" value="Отправить" name="submit"> 
	
</div> 
</form> 
<? 
} 

function complete_mail() {
		
		include $_SERVER['DOCUMENT_ROOT'] . '/mass.php';
		
		foreach ($arFields as $key => $value) {
	
		$_POST[$key] =  htmlspecialchars(trim($_POST[$key])); 

		$validate2 = explode(", ", $arFields[$key]['validate']);
	    
		if (in_array('email',$validate2))
		{//echo 'Нашел поле на проверку емайл';
		// если неправильно заполнено поле email - показываем ошибку
        if(!preg_match("/[0-9a-z_]+@[0-9a-z_^\.]+\.[a-z]{2,3}/i", $_POST[$key])) 
			{
				echo '<p> ' . $arFields[$key]['error'] . '</p>';
				show_form(); 
		        exit();
			}
		}
	
	    if (in_array('length',$validate2))
		{//echo 'Поле на проверку длинны';
		if (strlen($_POST[$key]) < 4)
			{
				echo '<p> ' . $arFields[$key]['error'] . '</p>';
				show_form(); 
				exit();
			
			}
		}
		}
		
		//Находим поле в котором написан email отправителя
	    foreach ($arFields as $key => $value) {
			
			$emailsend = explode(", ", $arFields[$key]['validate']);	    
		if (in_array('email',$emailsend))
		{
			$from = $_POST[$key];
		} else 
		{ $mess .=  $arFields[$key]['name'] . ': ' . $_POST[$key] . '  ';}	
		
		}
		
        $to = 'den090393@gmail.com'; 
        mail($to, 'Новое сообщение', $mess, "From:".$from); 
        echo 'Спасибо! Ваше письмо отправлено.<br>';
}

if (!empty($_POST['submit'])) complete_mail(); 
else show_form(); 
?>
  • Вопрос задан
  • 219 просмотров
Решения вопроса 3
webinar
@webinar Куратор тега PHP
Учим yii: https://youtu.be/-WRMlGHLgRg

<?php if ($arFields[$key]['type'] == 'text' )
{echo ' ';}
else
{echo '' . $_POST[$key] . '';}
?>

стоило бы написать так:
<?php if ($arFields[$key]['type'] == 'text' ) : ?>
    <input size="40" type="<?=$arFields[$key]['type']?> name="<?=$key . ' value ="' . $_POST[$key] ?>">
  <?php else: ?> 
    <textarea rows="10" cols="35" name="<?=$key?>"  ><?=$_POST[$key]?></textarea>
  <?php endif; ?>

Это касаемо читабельности. Плюс комменты не мешало бы делать в коде.
foreach тоже более читабельный в виде:
<?php foreach($fff as $key=>$value): ?>
тут html
<?php endforeach; ?>

Плюс куча лишних переносов и пустых строк, где они не нужны, и нет там где просятся.
ВОТ ЭТО ВАЩЕ ЗЛО:
<?php	
    } 
  ?>


ПС: почитайте www.php-fig.org/psr/psr-1
Ответ написан
Комментировать
jacksparrow
@jacksparrow
Если смотреть, на то что подчеркнули, то
foreach($arFields as $array){
//...
 $validate2 = explode(", ", $array['validate']);
//...

+ Ctr+ALT+L в шторме форматирует код в более читаемый вид
А если чуть более честно, формулировка крайне спорная, половине людей может не понравится их работа с массивами.
Добавленно: плюс слишком много проходов форичем, точно нельзя было за один разбор?
Ответ написан
Комментировать
@AlikDex
На продвинутого не претендую. Но как-то так:
<?php
/**
 *	Применяет рекурсивно ко всем элементам массива функции htmlspecialchars, stripslashes, trim.
 *	@param $arr array;
 *	@return $newArr array - обработанный массив.
 */
function array_stripslashes($arr)
{
	$newArr = is_array($arr) ?	array_map('array_stripslashes', $arr) :  htmlspecialchars(stripslashes(trim($arr)));
	return $newArr;
}
 
/**
 *	Типа массив для формы.
 */

$arFields = [
	'EMAIL' => [
		'name' => 'Email',
		'validate' => 'email, length', 
		'type' => 'text', 
		'error' => 'Email не введен либо введен неверно'
	],
	'NAME' => [
		'name' => 'Имя',
		'validate' => 'length', 
		'type' => 'text', 
		'error' => 'Введите имя'
	],
	'MESSAGE' => [
		'name' => 'Сообщение',
		'validate' => 'length', 
		'type' => 'textarea', 
		'error' => 'Введите сообщение'
	],
];

//require_once $_SERVER['DOCUMENT_ROOT'] . '/mass.php'; // хз че тут, закоментим.

if ($_POST['submit']) {
	$error = [];
    
	$_POST = array_map('array_stripslashes', $_POST); // почистим пост данные.

    foreach ($arFields as $key => $value) {
  
		if ($arFields[$key]['validate']) {
	    	$validateArr = array_map("trim", explode(",", $arFields[$key]['validate']));
	    
		    foreach ($validateArr as $validateParam) {

					// валидация по списку
		    	if ($validateParam === "email") {
		    		(filter_var($_POST[$key], FILTER_VALIDATE_EMAIL) === false) ? $error[$key][] = "Неверный емейл" : $userEmail = $_POST[$key];// Запомним емейл юзера, если он прошел валидацию.

		    	} elseif ($validateParam === "length") {
		    		(strlen($_POST[$key]) > 100) ? $error[$key][] = "Превышена допустимая длина" : false ;
		    	}
		    	
		    }
		}
    }

    if (empty($error)) {
		$from = 'den090393@gmail.com';
		$message = "Спасибо что пользуетесь нашим продуктом.";
		mail($userEmail, 'Новое сообщение', $message, "From:" . $from);
		
		$notify  = "Gисьмо отправлено на {$userEmail}<br>";
		$notify .= "<a href=\"http://mysite.com/\">Перейти на главную</a>";
		echo $notify;
		
		die();
	}
}
?>


<form action="" method="POST"> 
	<div align="left">

		<?php foreach ($arFields as $key => $value) : ?>
			<?php if (!empty($error[$key])): ?>
				<?= implode("<br>", $error[$key]) ?>
				<br>
			<?php endif; ?>
			
			<label><?= $arFields[$key]['name']?></label>
			<?php if ($arFields[$key]['type'] === 'textarea'): ?>
				<textarea rows="10" cols="35" name="<?=$key?>"><?= $_POST[$key]?></textarea>
			<?php else: ?>
				<input size="40" type="<?= $arFields[$key]['type']?>" name="<?= $key?>" value ="<?= $_POST[$key]?>">
			<?php endif; ?>

			<br>
		<?php endforeach; ?>	
	  
		<input type="submit" value="Отправить" name="submit"> 
	  
	</div> 
</form>


Касательно массива валидации.
Имхо было бы удобнее сделать так:
$arFields = [
	'email' => [
		'validate' => [
			'required',
			'email',
			'length' => 100,
		] 
		'type' => 'text', 
		'label' => 'Ваш емейл'
	],
	'name' => [
		'validate' => [
			'required',
			'length' => 40,
		], 
		'type' => 'text', 
		'label' => 'Введите имя'
	],
	'message' => [
		'validate' => [
			'required',
			'length' => 1000,
		], 
		'type' => 'textarea', 
		'label' => 'Введите сообщение'
	],
];
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
trevoga_su
@trevoga_su
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
YCLIENTS Москва
от 200 000 до 350 000 ₽
Ведисофт Екатеринбург
от 25 000 ₽
ИТЦ Аусферр Магнитогорск
от 100 000 до 160 000 ₽
25 апр. 2024, в 12:20
15000 руб./за проект
25 апр. 2024, в 12:08
300 руб./за проект
25 апр. 2024, в 11:49
25000 руб./за проект