Jump to content
php.lv forumi

MVC kļūdu izvadīšana


mandarīnpīle

Recommended Posts

Kāds ir labais stils un best practise lai kļūdu ziņojumu izvadītu no Modeļa līdz Skatam?

Piemēram, login forma datus nosūta Kontrollerim, tas savukārt Modelim, kas salīdzina datus ar datubāzi. Šobrīd modeļa metode login() returno true vai false. To uzķer Kontrolleris un attiecīgi vai nu vēlreiz ielādē login formu, vai kādu reģistrēto jūzeru Skatu. Kontrolleris:

$this->load->model('login_model');			
$did_you_logged_in = $this->login_model->login();

if($did_you_logged_in === TRUE){
	$view_data['main_content']	= 'members_area_view';
	$this->load->view('template_view', $view_data);
}
else{
	$view_data['main_content']	= 'login_form_view';
	$view_data['error'] 		= 'Ievadīti nepareizi login dati';

	$this->load->view('template_view', $view_data);
}

Šobrīd Kontrolleris, uzķerot false, izveido jaunu mainīgo $error un padot to skatam. Problēma ir tā, ka man jāpārbauda errora esamība manā template_view.php Skatā, kas savieno HTML lapas statisko header, $main_content, statisko footer. 

$this->load->view('static_header_view');

if(isset($error)){
	$this->load->view($main_content, $error);
}
else{
	$this->load->view($main_content);
}

$this->load->view('static_footer_view');

Un tad vēlreiz galvenajā $main_content Skatā:

if(isset($error)){
	echo $error;
}

Kopumā diezgan makaronīgs kods. Apskatījos netā par try catch blokiem, bet to te laikam nevar izmantot, jo kods, ko vajag ķert (try) atrodas modelī, bet izvade (catch) atrodas skatā. Vai nav kaut kāds labāks risinājums?

Edited by mandarīnpīle
Link to comment
Share on other sites

Ne obligāti... Ja kaut kas pamatīgi nofeilo, tad atsevišķs error skats, ja vienkārši kaut kas nepatīk, tad uzstādi viewam error variabli.

 

Šeit runa par "kaut kas nepatīk lietām". Nu kā jau piemērā - lietotājs ievadījis nepareizu login un paroli. Tad šis pats risinājums ir labs un nav iespējams nekas more DRY, more MVC vai more OOP?

$view_data['main_content']	= 'login_form_view';
$view_data['error'] 		= 'Ievadīti nepareizi login dati';

$this->load->view('template_view', $view_data);

Kur template_view.php ir

<!DOCTYPE html>
<html>
	<head>
		<title></title>
		<meta charset="UTF-8">
		<link rel="stylesheet" type="text/css" href="<?php echo base_url();?>/css/style.css">
		<script type="text/javascript" src="<?php echo base_url();?>/javascript/jquery-1.10.2.js"></script>
	</head>
	<body>
	<?php
		if(isset($error)){
			$this->load->view($main_content, $error);
		}
		else{
			$this->load->view($main_content);
		}
	?>
	</body>
</html>

Un tālāk login_form_view.php ir:

<?php

if(isset($error)){
	echo $error;
}
?>

<form>
...
</form>
Edited by mandarīnpīle
Link to comment
Share on other sites

man atkal ir globāls šis messages, kur var būt gan successful, gan errori, etc

teiksim 

 

ar to pašu try catch noķerarm erroru, tad $this->setError/setMessage(e->getMessage()) un tas tiek ielikts sesijā (session[messages][type]) un pirms izvadas saliek messageus iekšs variabļa un sesiju nodzēšam.

Šāds variants liekas labs, ja nepieciešams errors vai messages pēc refresha. 

function setMessage($message,$status='info') {
	$_SESSION['messages'][$status][] = $message;
    }
// handle errors & messages
$messages = '';
if(!empty($_SESSION['messages'])) {
  foreach($_SESSION['messages'] AS $type=>$messages_list) {
    $messages .= '<div class="messages '.$type.'"><ul>';
    foreach($messages_list AS $message) {
      $messages .= '<li>'.$message.'</li>';
    }
    $messages .= '</ul></div>';
  }
  unset($_SESSION['messages']);
}

un tad jau lapā vnk print $messages; un viss ($messages iet iekšs galvenā tēmas faila, vai tavā gadījumā pirms $main_content)

 

Šādā gadījumā sanāk, ka iekšs moduļu view'iem, nemaz nevajag nekādas pārbaudes par izvadi, jo tas ir izvadīts pirms tam. 

Edited by anonīms
Link to comment
Share on other sites

Protams, ka iespējams reizēm vajadzēs atšķirīgāi vietai (tas pats box, divs, sidebars, etc), bet nu pa lielam tomēr...

btw, vai man vienīgajam liekas, ka auzās ir iebraukts ar template_view? 

		if(isset($error)){
			$this->load->view($main_content, $error);
		}
		else{
			$this->load->view($main_content);
		}

kāpēc Tu to visu nepārbaudi pirms tam un pēc tam nepadod vienkārši variablim, lai beigās sanāk, piemēram, "print $content;"?

<html>
<head/>
<body>
<?php
		print '<h1 class="title">'.$title.'</h1>';
		print $messages;
		print $content;
?>
</body>
</html>
	      $plugin = new $plugin_name;
	      if(method_exists($plugin,$routes[1])) {
	        $content = call_user_func(array($plugin,$routes[1]));
		$title = $plugin->title;
	      }
Link to comment
Share on other sites

It's simply a coding habit. You can use echo or print, it makes very little difference. I use print whenever I'm using code that returns a value. Otherwise, I risk the code not working. I've noticed a lot of Wordpress theme designers don't understand this and use echo for almost everything. Print is better for functionality, echo is better for performance.

 

 

Šis jau tika miljons reizes izrunāts, gan šeit, gan citur forumos. Pirms 2011.gada vienmēr izmantoju echo, bet tagad pēc standariem darbā, jāraksta print, tāpēc arī pats saviem projektiem izmantoju. (man nekādas pretenzijas ne pret vienu, ne otru). 

 

http://fabien.potencier.org/article/8/print-vs-echo-which-one-is-faster

Edited by anonīms
Link to comment
Share on other sites

 

 

btw, vai man vienīgajam liekas, ka auzās ir iebraukts ar template_view? 

kāpēc Tu to visu nepārbaudi pirms tam un pēc tam nepadod vienkārši variablim, lai beigās sanāk, piemēram, "print $content;"?

 

Hm, es nesaprotu kur "pirms tam" es varu to pārbaudīt.. " Es nedaudz pārveidoju visu un šobrīd mans kontrolleris ķer errorus ar try catch bloku:

try{

	if($this->form_validation->run() === TRUE){

		if($did_you_logged_in === TRUE){
							
		}
		else{
			throw new Exception('Nepareiza parole un/vai lietotajvards.');	
		}

	}
	else{
		throw new Exception('Ievadīti pārāk īsi vai pārāk gari dati.');
	}

} catch(Exception $ex){
	$view_data['main_content']	= 'login_form_view';
	$view_data['error'] 		= $ex->getMessage();

	$this->load->view('template_view', $view_data);
}

Tad sekojošais template_view.php:

<!DOCTYPE html>
<html>
	<head></head>
	<body>
	<?php
		if(!isset($error)){
			$error = '';
		}

		$this->load->view($main_content, $error);
	?>
	</body>
</html>

Un sekojošais login_form_view.php

<?php
	echo $error;

	echo $form_open();
	...........
	echo $form_close();
?>

Man gan īsti nepatīk, jo, ja $error mainīgais nav, tad Skatam tiek padots tukšs mainīgais un tas tiek echo-outots, kas it kā ir nevajadzīgas darbības. Kā arī es gribu izmantot template_view.php priekš tādām lapām, kur nav paredzēts parādīt nekādus errorus. Tāpēc arī sākumā bija piemērs, kuru iepostoju iepriekš un Tev nepatika. Doma bija tāda ka template_view.php nodod $error mainīgo tikai tad, ja ir to saņēmis, respektīvi, tikai skatiem, kur tas ir paredzēts. Citiem skatiem $error nemaz netiek padots.

Link to comment
Share on other sites

 

 

Hm, es nesaprotu kur "pirms tam" es varu to pārbaudīt.. " Es nedaudz pārveidoju visu un šobrīd mans kontrolleris ķer errorus ar try catch bloku:

Nu iespējams mans gadījums atšķiras no tava. Es savu veco projektu uz oop sāku pārveidot aptuveni 2-3 nedēļas atpakaļ, bet man bija pieredze pirms tam ar oop, tāpēc varbūt sanāca to visu dabūt nesāpīgākā veidā. 

Ja Tu gribi kā spainis minēja, ka nav visur globālais $messages, tad jādara pēc viņa veida. Man gan ir savādāk. Man visi messages tiek turēti globālajā, tāpēc es errorus salieku iekšs sessijas un tieši pirms izvadas ($this->load->view man tiek uzstādīts vnk kā variablis, nevis uzreiz izvadīts). tiek saģenerēts $messages variablis. 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...