GET and POST Handlers
Controllers handle different HTTP methods through the execute() method.
GET handler (view/read):
<?php
namespace Vendor\Blog\Controller\Post;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
class View extends Action
{
public function __construct(
Context $context,
private \Vendor\Blog\Model\PostFactory $postFactory,
private \Magento\Framework\View\Result\PageFactory $pageFactory
) {
parent::__construct($context);
}
public function execute()
{
$id = $this->getRequest()->getParam('id');
$post = $this->postFactory->create()->load($id);
if (!$post->getId()) {
$this->messageManager->addErrorMessage(__('Post not found'));
return $this->_redirect('*/*/index');
}
$page = $this->pageFactory->create();
$page->getLayout()->getChildBlock('content')
->setPost($post);
return $page;
}
}
POST handler (create/update):
<?php
namespace Vendor\Blog\Controller\Post;
use Magento\Framework\App\Action\Action;
class Save extends Action
{
public function execute()
{
$postData = $this->getRequest()->getPostValue();
if (!$postData) {
return $this->_redirect('*/*/index');
}
try {
$post = $this->postFactory->create();
$post->setData($postData);
$post->save();
$this->messageManager->addSuccessMessage(__('Post saved successfully'));
return $this->_redirect('*/*/view', ['id' => $post->getId()]);
} catch (\Exception $e) {
$this->messageManager->addErrorMessage($e->getMessage());
return $this->_redirect('*/*/edit', ['id' => $postData['entity_id'] ?? null]);
}
}
}
GET parameters:
// /blog/post/view/id/5
$id = $this->getRequest()->getParam('id'); // 5
// Query parameters
$page = $this->getRequest()->getParam('p', 1); // Default 1
// All parameters
$params = $this->getRequest()->getParams();
Form Validation
Controllers validate submitted data before processing.
Server-side validation:
public function execute()
{
$postData = $this->getRequest()->getPostValue();
// Validate required fields
if (empty($postData['title'])) {
$this->messageManager->addErrorMessage(__('Title is required'));
return $this->_redirect('*/*/edit', $postData);
}
// Validate email
if (!filter_var($postData['email'], FILTER_VALIDATE_EMAIL)) {
$this->messageManager->addErrorMessage(__('Invalid email address'));
return $this->_redirect('*/*/edit', $postData);
}
// Validate length
if (strlen($postData['title']) > 255) {
$this->messageManager->addErrorMessage(__('Title must be less than 255 characters'));
return $this->_redirect('*/*/edit', $postData);
}
// Process valid data
// ...
}
Using DataObjectHelper for validation:
public function execute()
{
$postData = $this->getRequest()->getPostValue();
$post = $this->postFactory->create();
$this->dataObjectHelper->populateWithArray(
$post,
$postData,
\Vendor\Blog\Api\Data\PostInterface::class
);
// Validate via model
$validator = $this->validatorFactory->create();
if (!$validator->isValid($post)) {
foreach ($validator->getErrors() as $error) {
$this->messageManager->addErrorMessage($error);
}
return $this->_redirect('*/*/edit');
}
$post->save();
}
Custom validation:
private function validate(array $data): array
{
$errors = [];
if (empty($data['name'])) {
$errors[] = __('Name is required');
}
if (!empty($data['email']) && !filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
$errors[] = __('Invalid email format');
}
if (!empty($data['website']) && !filter_var($data['website'], FILTER_VALIDATE_URL)) {
$errors[] = __('Invalid URL format');
}
return $errors;
}
Error Handling Patterns
Proper error handling improves user experience and debugging.
Exception-based error handling:
public function execute()
{
try {
$this->processData();
$this->messageManager->addSuccessMessage(__('Operation completed successfully'));
return $this->_redirect('*/*/index');
} catch (\Magento\Framework\Exception\LocalizedException $e) {
// User-facing errors
$this->messageManager->addErrorMessage($e->getMessage());
} catch (\Exception $e) {
// System errors
$this->messageManager->addErrorMessage(__('An error occurred. Please try again later.'));
$this->_objectManager->get(\Psr\Log\LoggerInterface::class)->critical($e);
}
return $this->_redirect('*/*/index');
}
Error types in Magento:
LocalizedException → User-facing errors
\Exception → System errors (logged)
NoSuchEntityException → Entity not found
AlreadyExistsException → Duplicate entry
InputException → Invalid input
AuthorizationException → Permission denied
Handling specific exceptions:
try {
$this->orderService->process($orderId);
} catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
$this->messageManager->addErrorMessage(__('Order not found'));
return $this->_redirect('sales/order/index');
} catch (\Magento\Framework\Exception\AlreadyExistsException $e) {
$this->messageManager->addErrorMessage(__('Order already processed'));
} catch (\Magento\Framework\Exception\LocalizedException $e) {
$this->messageManager->addErrorMessage($e->getMessage());
} catch (\Exception $e) {
$this->messageManager->addErrorMessage(__('Processing failed'));
$this->logger->critical($e);
}
Message Manager Patterns
Message manager provides user feedback for operations.
Message types:
// Success message
$this->messageManager->addSuccessMessage(__('Saved successfully'));
// Error message
$this->messageManager->addErrorMessage(__('An error occurred'));
// Warning message
$this->messageManager->addWarningMessage(__('Please review your input'));
// Notice message
$this->messageManager->addNoticeMessage(__('This is a notice'));
Translatable messages:
// Use __() for translatable strings
$this->messageManager->addSuccessMessage(
__('%1 product(s) updated successfully', $count)
);
// With HTML (use carefully)
$this->messageManager->addSuccessMessage(
__('Saved. <a href="%1">View</a>', $url)
);
Redirect with messages:
// Success + redirect
$this->messageManager->addSuccessMessage(__('Saved'));
return $this->_redirect('*/*/view', ['id' => $id]);
// Error + redirect back
$this->messageManager->addErrorMessage(__('Failed'));
return $this->_redirect('*/*/edit', ['id' => $id]);
// Clear messages on redirect
$this->messageManager->getMessages(true);
Display messages in template:
// In PHTML template
<?php
$messages = $block->getMessages();
if ($messages) {
foreach ($messages->getItems() as $message) {
echo '<div class="message ' . $message->getType() . '">';
echo $message->getText();
echo '</div>';
}
}
?>
Quiz
1. What method handles all HTTP requests in a controller?
2. How do you get POST data in a controller?
3. What exception type is used for user-facing errors?
4. What message type should be used for successful operations?
Flashcards
Question
How do you get a URL parameter?
Click to reveal answer
Answer
$this->getRequest()->getParam('param_name')
Question
What is the POST data access method?
Click to reveal answer
Answer
$this->getRequest()->getPostValue()
Question
What exception is for user-facing errors?
Click to reveal answer
Answer
Magento\Framework\Exception\LocalizedException
Question
How do you add a success message?
Click to reveal answer
Answer
$this->messageManager->addSuccessMessage(__('Message'))
Question
What should controllers always return?
Click to reveal answer
Answer
ResultInterface (Page, Json, Redirect, etc.)
Revision Notes
Key Takeaways
- 1. execute() handles all HTTP requests in a controller
- 2. Use getRequest()->getParam() for URL params, getPostValue() for POST data
- 3. Validate data server-side before processing
- 4. Handle exceptions: LocalizedException for users, \Exception for logging
- 5. Message types: Success, Error, Warning, Notice
- 6. Always redirect after POST to prevent duplicate submissions
Interview Tips
- • Explain GET vs POST handling patterns
- • Describe form validation approaches
- • Discuss exception handling hierarchy
- • Know how to use message manager effectively
Cheat Sheet
Action Patterns Cheat Sheet
GET:
$id = $this->getRequest()->getParam('id');
return $this->pageFactory->create();
POST:
$data = $this->getRequest()->getPostValue();
$model->setData($data)->save();
return $this->_redirect('*/*/view', ['id' => $id]);
Validation:
- Check required fields
- Validate formats (email, URL)
- Use model validators
Error handling:
try {
// Process
} catch (LocalizedException $e) {
$this->messageManager->addErrorMessage($e->getMessage());
} catch (\Exception $e) {
$this->logger->critical($e);
}
Messages:
- addSuccessMessage()
- addErrorMessage()
- addWarningMessage()
- addNoticeMessage()