{"id":77,"date":"2025-09-21T05:22:38","date_gmt":"2025-09-21T08:22:38","guid":{"rendered":"https:\/\/diegoelias.dev\/pt\/?p=77"},"modified":"2025-09-30T12:34:46","modified_gmt":"2025-09-30T15:34:46","slug":"arquiteturas-e-padroes-em-php","status":"publish","type":"post","link":"https:\/\/diegoelias.dev\/pt\/blog\/php\/arquiteturas-e-padroes-em-php\/","title":{"rendered":"Arquiteturas e padr\u00f5es em PHP"},"content":{"rendered":"<p>PHP Procedural<\/p>\n<ol>\n<li>Microsservi\u00e7os (procedural): endpoints com fun\u00e7\u00f5es.<\/li>\n<li>Monolith MVC<\/li>\n<\/ol>\n<ul>\n<li>Model Procedural: fun\u00e7\u00f5es que consultam o banco de dados.<\/li>\n<li>View Procedural: HTML + vari\u00e1veis PHP (include, require).<\/li>\n<li>Controller Procedural: recebe a requisi\u00e7\u00e3o ($_GET, $_POST), chama fun\u00e7\u00f5es do model e carrega a view.<\/li>\n<\/ul>\n<p>PHP OOP<\/p>\n<ol>\n<li>Microsservi\u00e7os (OOP): servi\u00e7os encapsulados em classes e\/ou alternativa usando DAO.<\/li>\n<li>Monolith MVC<\/li>\n<\/ol>\n<ul>\n<li>Model com DAO: DAO para acesso aos dados, Model para l\u00f3gica.<\/li>\n<li>Model OOP: o model gerencia a l\u00f3gica de neg\u00f3cio e a persist\u00eancia na mesma classe.<\/li>\n<li>View OOP: classes ou componentes respons\u00e1veis pela renderiza\u00e7\u00e3o da interface.<\/li>\n<li>Controller OOP: classes controller ou um front controller centralizado.<\/li>\n<\/ul>\n<p>Exemplos usando MySQL:<\/p>\n<p><strong>Microsservi\u00e7os (Procedural RESTful)<\/strong><\/p>\n<p>\/api\/db.php<\/p>\n<pre><code>&lt;?php\r\nfunction getConnection(\r\n    string $host = \"localhost\",\r\n    string $user = \"root\",\r\n    string $password = \"\",\r\n    string $database = \"mi_base\"\r\n): mysqli {\r\n    $conn = mysqli_connect($host, $user, $password, $database);\r\n    if (!$conn) {\r\n        die(\"Erro de conex\u00e3o: \" . mysqli_connect_error());\r\n    }\r\n    return $conn;\r\n}<\/code><\/pre>\n<p>\/api\/users\/index.php<\/p>\n<pre><code>&lt;?php\r\nheader(\"Content-Type: application\/json\");\r\nrequire \"users.php\";\r\n\r\n$method = $_SERVER[\"REQUEST_METHOD\"];\r\n$id = 0;\r\nif (isset($_GET[\"id\"])) {\r\n    $id = (int) $_GET[\"id\"];\r\n}\r\n\r\nswitch ($method) {\r\n    case \"GET\": {\r\n        if ($id !== 0) {\r\n            echo json_encode(getUserById($id));\r\n        } else {\r\n            echo json_encode(getUsers());\r\n        }\r\n        break;\r\n    }\r\n    case \"POST\": {\r\n        $data = json_decode(file_get_contents(\"php:\/\/input\"), true);\r\n        echo json_encode(createUser($data));\r\n        http_response_code(201);\r\n        break;\r\n    }\r\n    default: {\r\n        http_response_code(405);\r\n        echo json_encode(array(\"error\" => \"M\u00e9todo n\u00e3o permitido\"));\r\n        break;\r\n    }\r\n}<\/code><\/pre>\n<p>\/api\/users\/users.php<\/p>\n<pre><code>&lt;?php\r\nrequire __DIR__ . \"\/..\/db.php\";\r\n\r\nfunction getUsers(): array {\r\n    $conn = getConnection();\r\n    $sql = \"SELECT id, name FROM users\";\r\n    $result = mysqli_query($conn, $sql);\r\n\r\n    $usuarios = array();\r\n    while ($row = mysqli_fetch_assoc($result)) {\r\n        $usuarios[] = $row;\r\n    }\r\n    mysqli_close($conn);\r\n    return $usuarios;\r\n}\r\n\r\nfunction getUserById(int $id): array {\r\n    $conn = getConnection();\r\n    $stmt = mysqli_prepare($conn, \"SELECT id, name FROM users WHERE id = ?\");\r\n    mysqli_stmt_bind_param($stmt, \"i\", $id);\r\n    mysqli_stmt_execute($stmt);\r\n    $result = mysqli_stmt_get_result($stmt);\r\n    $usuario = mysqli_fetch_assoc($result);\r\n    if (!$usuario) {\r\n        $usuario = array();\r\n    }\r\n    mysqli_stmt_close($stmt);\r\n    mysqli_close($conn);\r\n    return $usuario;\r\n}\r\n\r\nfunction createUser(array $data): array {\r\n    $name = \"Desconhecido\";\r\n    if (isset($data[\"name\"]) && is_string($data[\"name\"]) && trim($data[\"name\"]) !== \"\") {\r\n        $name = trim($data[\"name\"]);\r\n    }\r\n\r\n    $conn = getConnection();\r\n    $stmt = mysqli_prepare($conn, \"INSERT INTO users (name) VALUES (?)\");\r\n    mysqli_stmt_bind_param($stmt, \"s\", $name);\r\n    mysqli_stmt_execute($stmt);\r\n\r\n    $id = mysqli_insert_id($conn);\r\n\r\n    mysqli_stmt_close($stmt);\r\n    mysqli_close($conn);\r\n\r\n    return array(\"id\" => (int)$id, \"name\" => $name);\r\n}<\/code><\/pre>\n<p><strong>MVC Procedural<\/strong><\/p>\n<p>model.php<\/p>\n<pre><code>&lt;?php\r\nrequire \"db.php\";\r\n\r\nfunction getUsers(): array {\r\n    $conn = getConnection();\r\n    $sql = \"SELECT id, name FROM users\";\r\n    $result = mysqli_query($conn, $sql);\r\n\r\n    $usuarios = array();\r\n    while ($row = mysqli_fetch_assoc($result)) {\r\n        $usuarios[] = $row;\r\n    }\r\n    mysqli_close($conn);\r\n    return $usuarios;\r\n}<\/code><\/pre>\n<p>view.php<\/p>\n<pre><code>&lt;?php\r\n&lt;h1>Usu\u00e1rios&lt;\/h1>\r\n&lt;ul>\r\n&lt;?php\r\nfor ($i = 0; $i &lt; count($usuarios); $i++) {\r\n    echo \"&lt;li>\" . htmlspecialchars($usuarios[$i][\"name\"]) . \"&lt;\/li>\";\r\n}\r\n?>\r\n&lt;\/ul><\/code><\/pre>\n<p>controller.php<\/p>\n<pre><code>&lt;?php\r\nrequire \"model.php\";\r\n$usuarios = getUsers();\r\ninclude \"view.php\";<\/code><\/pre>\n<p><strong>Microsservi\u00e7os (OOP RESTful)<\/strong><\/p>\n<p>\/api\/db.php<\/p>\n<pre><code>&lt;?php\r\nclass Database {\r\n    public static function getConnection(\r\n        string $host = \"localhost\",\r\n        string $user = \"root\",\r\n        string $password = \"\",\r\n        string $database = \"mi_base\"\r\n    ): mysqli {\r\n        $conn = new mysqli($host, $user, $password, $database);\r\n        if ($conn->connect_error) {\r\n            die(\"Erro de conex\u00e3o: \" . $conn->connect_error);\r\n        }\r\n        return $conn;\r\n    }\r\n}<\/code><\/pre>\n<p>\/api\/users\/index.php<\/p>\n<pre><code>&lt;?php\r\nheader(\"Content-Type: application\/json\");\r\nrequire \"UserService.php\";\r\n\r\n$service = new UserService();\r\n$method = $_SERVER[\"REQUEST_METHOD\"];\r\n$id = 0;\r\nif (isset($_GET[\"id\"])) {\r\n    $id = (int) $_GET[\"id\"];\r\n}\r\n\r\nswitch ($method) {\r\n    case \"GET\": {\r\n        if ($id !== 0) {\r\n            echo json_encode($service->getUserById($id));\r\n        } else {\r\n            echo json_encode($service->getUsers());\r\n        }\r\n        break;\r\n    }\r\n    case \"POST\": {\r\n        $data = json_decode(file_get_contents(\"php:\/\/input\"), true);\r\n        echo json_encode($service->createUser($data));\r\n        http_response_code(201);\r\n        break;\r\n    }\r\n    default: {\r\n        http_response_code(405);\r\n        echo json_encode(array(\"error\" => \"M\u00e9todo n\u00e3o permitido\"));\r\n        break;\r\n    }\r\n}<\/code><\/pre>\n<p>\/api\/users\/UserService.php<\/p>\n<pre><code>&lt;?php\r\nrequire __DIR__ . \"\/..\/db.php\";\r\n\r\nclass UserService {\r\n    public function getUsers(): array {\r\n        $conn = Database::getConnection();\r\n        $sql = \"SELECT id, name FROM users\";\r\n        $result = $conn->query($sql);\r\n\r\n        $usuarios = array();\r\n        while ($row = $result->fetch_assoc()) {\r\n            $usuarios[] = $row;\r\n        }\r\n        $conn->close();\r\n        return $usuarios;\r\n    }\r\n\r\n    public function getUserById(int $id): array {\r\n        $conn = Database::getConnection();\r\n        $stmt = $conn->prepare(\"SELECT id, name FROM users WHERE id = ?\");\r\n        $stmt->bind_param(\"i\", $id);\r\n        $stmt->execute();\r\n        $result = $stmt->get_result();\r\n        $usuario = $result->fetch_assoc();\r\n        if (!$usuario) {\r\n            $usuario = array();\r\n        }\r\n        $stmt->close();\r\n        $conn->close();\r\n        return $usuario;\r\n    }\r\n\r\n    public function createUser(array $data): array {\r\n        $name = \"Desconocido\";\r\n        if (isset($data[\"name\"]) && is_string($data[\"name\"]) && trim($data[\"name\"]) !== \"\") {\r\n            $name = trim($data[\"name\"]);\r\n        }\r\n\r\n        $conn = Database::getConnection();\r\n        $stmt = $conn->prepare(\"INSERT INTO users (name) VALUES (?)\");\r\n        $stmt->bind_param(\"s\", $name);\r\n        $stmt->execute();\r\n        $id = $conn->insert_id;\r\n\r\n        $stmt->close();\r\n        $conn->close();\r\n\r\n        return array(\"id\" => (int)$id, \"name\" => $name);\r\n    }\r\n}<\/code><\/pre>\n<p><strong>Microsservi\u00e7os (OOP RESTful com DAO)<\/strong><\/p>\n<p>\/api\/users\/UserDAO.php<\/p>\n<pre><code>&lt;?php\r\nrequire __DIR__ . \"\/..\/db.php\";\r\n\r\nclass UserDAO {\r\n    public function getAll(): array {\r\n        $conn = Database::getConnection();\r\n        $sql = \"SELECT id, name FROM users\";\r\n        $result = $conn->query($sql);\r\n\r\n        $usuarios = array();\r\n        while ($row = $result->fetch_assoc()) {\r\n            $usuarios[] = $row;\r\n        }\r\n        $conn->close();\r\n        return $usuarios;\r\n    }\r\n\r\n    public function getById(int $id): array {\r\n        $conn = Database::getConnection();\r\n        $stmt = $conn->prepare(\"SELECT id, name FROM users WHERE id = ?\");\r\n        $stmt->bind_param(\"i\", $id);\r\n        $stmt->execute();\r\n        $result = $stmt->get_result();\r\n        $usuario = $result->fetch_assoc();\r\n        if (!$usuario) {\r\n            $usuario = array();\r\n        }\r\n        $stmt->close();\r\n        $conn->close();\r\n        return $usuario;\r\n    }\r\n\r\n    public function create(array $data): array {\r\n        $name = \"Desconhecido\";\r\n        if (isset($data[\"name\"]) && is_string($data[\"name\"]) && trim($data[\"name\"]) !== \"\") {\r\n            $name = trim($data[\"name\"]);\r\n        }\r\n\r\n        $conn = Database::getConnection();\r\n        $stmt = $conn->prepare(\"INSERT INTO users (name) VALUES (?)\");\r\n        $stmt->bind_param(\"s\", $name);\r\n        $stmt->execute();\r\n        $id = $conn->insert_id;\r\n\r\n        $stmt->close();\r\n        $conn->close();\r\n\r\n        return array(\"id\" => (int)$id, \"name\" => $name);\r\n    }\r\n}<\/code><\/pre>\n<p>\/api\/users\/UserService.php<\/p>\n<pre><code>&lt;?php\r\nrequire \"UserDAO.php\";\r\n\r\nclass UserService {\r\n    private UserDAO $dao;\r\n\r\n    public function __construct() {\r\n        $this->dao = new UserDAO();\r\n    }\r\n\r\n    public function getUsers(): array {\r\n        return $this->dao->getAll();\r\n    }\r\n\r\n    public function getUserById(int $id): array {\r\n        return $this->dao->getById($id);\r\n    }\r\n\r\n    public function createUser(array $data): array {\r\n        return $this->dao->create($data);\r\n    }\r\n}<\/code><\/pre>\n<p>\/api\/users\/index.php<\/p>\n<pre><code>&lt;?php\r\nheader(\"Content-Type: application\/json\");\r\nrequire \"UserService.php\";\r\n\r\n$service = new UserService();\r\n$method = $_SERVER[\"REQUEST_METHOD\"];\r\n$id = 0;\r\nif (isset($_GET[\"id\"])) {\r\n    $id = (int) $_GET[\"id\"];\r\n}\r\n\r\nswitch ($method) {\r\n    case \"GET\": {\r\n        if ($id !== 0) {\r\n            echo json_encode($service->getUserById($id));\r\n        } else {\r\n            echo json_encode($service->getUsers());\r\n        }\r\n        break;\r\n    }\r\n    case \"POST\": {\r\n        $data = json_decode(file_get_contents(\"php:\/\/input\"), true);\r\n        echo json_encode($service->createUser($data));\r\n        http_response_code(201);\r\n        break;\r\n    }\r\n    default: {\r\n        http_response_code(405);\r\n        echo json_encode(array(\"error\" => \"M\u00e9todo n\u00e3o permitido\"));\r\n        break;\r\n    }\r\n}<\/code><\/pre>\n<p><strong>MVC OOP<\/strong><\/p>\n<p><strong>Model com DAO<\/strong><\/p>\n<p>UserDAO.php<\/p>\n<pre><code>&lt;?php\r\nrequire \"db.php\";\r\n\r\nclass UserDAO {\r\n    public function getAll(): array {\r\n        $conn = Database::getConnection();\r\n        $sql = \"SELECT id, name FROM users\";\r\n        $result = $conn->query($sql);\r\n\r\n        $usuarios = array();\r\n        while ($row = $result->fetch_assoc()) {\r\n            $usuarios[] = $row;\r\n        }\r\n        $conn->close();\r\n        return $usuarios;\r\n    }\r\n}<\/code><\/pre>\n<p>UserModel.php<\/p>\n<pre><code>&lt;?php\r\nrequire \"UserDAO.php\";\r\n\r\nclass UserModel {\r\n    private UserDAO $dao;\r\n\r\n    public function __construct() {\r\n        $this->dao = new UserDAO();\r\n    }\r\n\r\n    public function allUsers(): array {\r\n        return $this->dao->getAll();\r\n    }\r\n}<\/code><\/pre>\n<p><strong>Model OOP (sem DAO, tudo na classe)<\/strong><\/p>\n<p>UserModel.php<\/p>\n<pre><code>&lt;?php\r\nrequire \"db.php\";\r\n\r\nclass UserModel {\r\n    public function allUsers(): array {\r\n        $conn = Database::getConnection();\r\n        $sql = \"SELECT id, name FROM users\";\r\n        $result = $conn->query($sql);\r\n\r\n        $usuarios = array();\r\n        while ($row = $result->fetch_assoc()) {\r\n            $usuarios[] = $row;\r\n        }\r\n        $conn->close();\r\n        return $usuarios;\r\n    }\r\n}<\/code><\/pre>\n<p><strong>View OOP<\/strong><\/p>\n<p>UserView.php<\/p>\n<pre><code>&lt;?php\r\nclass UserView {\r\n    public function render(array $usuarios): void {\r\n        ?>\r\n        &lt;h1>Usu\u00e1rios&lt;\/h1>\r\n        &lt;ul>\r\n        &lt;?php\r\n        for ($i = 0; $i &lt; count($usuarios); $i++) {\r\n            echo \"&lt;li>\" . htmlspecialchars($usuarios[$i][\"name\"]) . \"&lt;\/li>\";\r\n        }\r\n        ?>\r\n        &lt;\/ul>\r\n        &lt;?php\r\n    }\r\n}<\/code><\/pre>\n<p><strong>Controller OOP (Clases Controller)<\/strong><\/p>\n<p>UserController.php<\/p>\n<pre><code>&lt;?php\r\nrequire \"UserModel.php\";\r\nrequire \"UserView.php\";\r\n\r\nclass UserController {\r\n    private UserModel $model;\r\n    private UserView $view;\r\n\r\n    public function __construct() {\r\n        $this->model = new UserModel();\r\n        $this->view = new UserView();\r\n    }\r\n\r\n    public function index(): void {\r\n        $usuarios = $this->model->allUsers();\r\n        $this->view->render($usuarios);\r\n    }\r\n}\r\n\r\n$controller = new UserController();\r\n$controller->index();<\/code><\/pre>\n<p><strong>Controller OOP (Front Controller)<\/strong><\/p>\n<p>index.php<\/p>\n<pre><code>&lt;?php\r\nrequire \"UserController.php\";\r\n\r\n$path = \"users\/index\";\r\nif (isset($_GET[\"path\"])) {\r\n    $path = $_GET[\"path\"];\r\n}\r\n\r\n$parts = explode(\"\/\", $path);\r\n\r\nif (count($parts) === 2) {\r\n    $controllerName = $parts[0];\r\n    $method = $parts[1];\r\n\r\n    if ($controllerName === \"users\") {\r\n        $controller = new UserController();\r\n        if (method_exists($controller, $method)) {\r\n            $controller->$method();\r\n        } else {\r\n            echo \"404 Not Found\";\r\n        }\r\n    } else {\r\n        echo \"404 Not Found\";\r\n    }\r\n} else {\r\n    echo \"404 Not Found\";\r\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>PHP Procedural Microsservi\u00e7os (procedural): endpoints com fun\u00e7\u00f5es. Monolith MVC Model Procedural: fun\u00e7\u00f5es que consultam o banco de dados. View Procedural: HTML + vari\u00e1veis PHP (include, require). Controller Procedural: recebe a requisi\u00e7\u00e3o ($_GET, $_POST), chama fun\u00e7\u00f5es do model e carrega a view. PHP OOP Microsservi\u00e7os (OOP): servi\u00e7os encapsulados em classes e\/ou alternativa usando DAO. Monolith MVC [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[17],"tags":[],"class_list":["post-77","post","type-post","status-publish","format-standard","hentry","category-php"],"_links":{"self":[{"href":"https:\/\/diegoelias.dev\/pt\/wp-json\/wp\/v2\/posts\/77","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/diegoelias.dev\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/diegoelias.dev\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/diegoelias.dev\/pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/diegoelias.dev\/pt\/wp-json\/wp\/v2\/comments?post=77"}],"version-history":[{"count":37,"href":"https:\/\/diegoelias.dev\/pt\/wp-json\/wp\/v2\/posts\/77\/revisions"}],"predecessor-version":[{"id":125,"href":"https:\/\/diegoelias.dev\/pt\/wp-json\/wp\/v2\/posts\/77\/revisions\/125"}],"wp:attachment":[{"href":"https:\/\/diegoelias.dev\/pt\/wp-json\/wp\/v2\/media?parent=77"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/diegoelias.dev\/pt\/wp-json\/wp\/v2\/categories?post=77"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/diegoelias.dev\/pt\/wp-json\/wp\/v2\/tags?post=77"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}