首先要做的就是整理你写的类。这还不错,但是您错过了正确的行话,然后就有点混乱了。我想我会添加一些建议来让您继续前进。
Setter 和 getter 函数是您可以用来操作对象私有字段而不利用它们的函数。例如,它们对于对要存储在类实例中的值进行完整性检查很有用。
通常它们被称为 get 和 set。您可以使用 automagic 函数来创建它们,但对我来说,您节省了一些输入,但必须与 ide 的自动完成作斗争,而且方法太通用了。
您需要将类的代码与从数据库加载/存储值或从网络检索用户输入的代码分开。每段代码只需要做一件事(并尽你所能)。
class User {
private $name;
private $birthdate;
private $age;
private $department;
private $id; // if you save in a db, you need an id
function __construct()
{
$this->id = 0;
$this->$name = '';
$this->birthdate = '';
$this->age = '';
$this->department = '';
}
function getId(): Int
{
return $this->id;
}
function setId($id) {
// check if $id contains a correct value (left as exercise)
$this->id = $id;
}
function setName(String $name)
{
if ($name === '') {
throw new \UnexpectedValueException("The user name is empty");
}
$this->name = $name;
}
function getName(): String
{
return $this->name;
}
/**
* The format of the field is YYYY/mm/dd, but you do not have to
* struggle with the format you need when you create your setter,
* keep you interface easy to use (you'll do it a lot of times),
* not to code (you need to wrote it just once).
*
* I will do just some obvious check for a valid date, just to
* show the point, you will have to complete them.
*
* The issue here is that the setter check the value before storing it
* to assure the developer that the value stored are valid ones (is not
* that simple usually)
**/
function setBirtdate(Int $day, Int $month, Int $year)
{
if ($day > 31) {
throw new \UnexpectedValueException("Invalid day of the month");
}
if ($month < 1 or $month > 12) {
throw new \UnexpectedValueException("This month does not exists");
}
if ($month == 2 ans $day > 29) {
throw new \UnexpectedValueException("February has just 28 days (29 in the leap years)");
}
/* add other checks there, how about the 31 of April, for example?) */
$this->birthDate = sprintf("%04d-%02d-%02d", $year, $month, $day);
}
/**
* You can have more than a setter, if you need to accomodate different
* use case for storing a value.
* If you live in the USA, maybe you want to stick with their common
* date format.
*
* As you see, it is a facade, I do not duplicate the code that manipulate
* the value, just stick with the canonical one, it will spare a lot of
* headache in you (near) future
**/
function setBirtdate_USA_format(Int $month, Int $day, Int $year)
{
$this->setBirthday($day, $month, $year);
}
/**
* Same with the getter, but only one does the work
* CHECK THE VALUE
* If you need a getter and a setter that get just
* your native format, and checks if it make sense,
* feel free to write it by yourself :-)
**/
function getBirthdate()
{
list($year, $month, $day) = explode("/", $this->birthdate);
return [$day, $month, $year];
}
function getBirthdate_USA_format()
{
list($day, $month, $year) = $this->getBirtdate();
return [$month, $day, $year];
}
function setAge($age)
{
if ($age < 1) {
throw new \UnexpectedValueException("No newborn allowed, please");
}
$this->age = $age;
}
function getAge()
{
return $this->age;
}
/**
* This is an interesting one, how discover if the department
* exists, or the string is not mispelled?
* There are a lot of valid ways to do this check, but it
* depends on the environment you are in, maybe there is a
* class Department, you can leverage, or a higher level one,
* which mantains a list of departments in place.
*
* We will resort to an hardcoded lists of valid deps, just to
* keep the example (not so) short and simple.
**/
function setDepartment($departmentName)
{
$knowDeps = ['Human Resource', 'Sales', 'Legal'];
if (!in_array($departmentName, $knowDeps)) {
throw new \UnexpectedValueException("The department {$departmentName} does not exists");
}
$this->department = $departmenetName;
}
function getDepartment()
{
return $this->department;
}
function save($dbc)
{
/* put the code for saving data to the db here */
}
}
这只是此类课程的初稿,在 cmets 中有很多乱七八糟的内容,以帮助您了解其中的内容。
是时候考虑 HTML,您将需要另一个类,通常称为 View,它获取用户对象并创建网页。根据您需要完成的任务,您可以选择多个。
以下是一个快速而肮脏的解决方案,只是为了展示如何使用我们的用户对象,有些是填充的。
假设我们在 /path/to/template/ 目录中有两个 html 片段文件。让我们称它们为 base.html.template 和 contactform.html.template
base.html 文件是:
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-8">
<h1>{{ contentTitle }}</h1>
{{ content }}
</div>
</div>
</div>
</body>
</html>
contactform.html 文件是:
<form name="contact-form" action="insert.php" method="POST" id="contact-form">
<input name="uid" value="{{ uid }}" type="hidden">
<div class="form-group">
<label for="Name">Name</label>
<input name="Name" value="{{ userName }}" type="text" class="form-control" name="Name" placeholder="Name" required>
</div>
<div class="form-group">
<label for="Birthday">Birthday</label>
<input name="Birth" value="{{ userBday }}" type="text" class="form-control" placeholder="YYYY/MM/DD" required>
</div>
<div class="form-group">
<label for="Age">Age</label>
<input name="Age" value="{{ userAge }}˝ type="text" class="form-control" name="Age" placeholder="Your Age" required>
</div>
<div class="form-group">
<label for="Depart">Department</label>
<input name="Depart" value="{{ userDep }}" type="text" class="form-control" placeholder="Your Department" required>
</div>
<button type="submit" class="btn btn-primary" name="submit" value="Submit" id="submit_form">Submit</button>
</form>
{{ userName }} jibberish 是我们在创建要在浏览器中显示的页面时需要用实际数据替换的占位符
class UserViewContactForm {
private $template;
function __construct() {
/* We need to load a template somehow. */
$this->template = file_get_contents(`/path/to/template/contactform.html`);
}
function render(?User $user=Null) {
/* When we do not pass any user, just show the form, otherwise
* we will fill it with the data of the user we have
* to show/edit
*/
if (!$user) {
$user = new User();
}
$fields = [
"{{ uid }} => $user->getId(),
"{{ userName }}" => $user->getName(),
"{{ userBday }}" => $user->getBirthday(),
"{{ userAge }}" => $user->getAge(),
"{{ userDep }}" => $user->getDepartment()
];
// get a copy of the template, maybe we'll need it for another one
$htmlform = $this->template;
// change all the placeholder
foreach ($fields as $field => $value) {
$htmlform = str_replace($field, $value, $htmlform);
}
return $htmlform;
}
}
我们需要一个 BaseView 对象来组装完整的 html 页面:
class HtmlPage {
private $template;
function __construct() {
/* We need to load a template somehow. */
$this->template = file_get_contents(`/path/to/template/base.html`);
}
function render($content) {
/* When we do not pass any user, just show the form, otherwise
* we will fill it with the data of the user we have
* to show/edit
*/
// get a copy of the template, maybe we will need to show another
// user in the next future, who know.
$htmlform = $this->template;
// change all the placeholder
foreach ($fields as $field => $value) {
$htmlform = str_replace($field, $value, $htmlform);
}
return $htmlform;
}
}
现在您的用户类与 html 解耦了,您可以在不更改保存您宝贵数据的类的情况下更改视图。
我们只需要一个工厂来根据我们从网络用户那里获得的输入来创建我们的用户。或来自数据库,或来自任何其他来源。
这是一个全新的任务,所以我们需要一个全新的对象。
这个类的任务是创建一个用户
Class UserFactory {
private $dbc;
function setDbConnector($pdo) {
/* just injecting an object to manage the interaction with a db */
$this->dbc = $pdo;
}
function createFromHash($data) {
/* Sometime you will need to use different verbs to
* send data to the server, hance the need to
* decouple the array we take the data from.
*
* Important, we should take the time here to
* check the input for malicious input.
* Since it is an example and I'm too lazy we will
* skip this important phase of input retrieving.
*/
$requiredFields = ['uid', 'Name', 'Birth', 'Age', 'Depart'];
$actual = array_intersect($requiredFields, array_keys($data));
if (count($requiredFields) != count($actual)) {
throw new \InvalidArgumentException("Some field is missing");
}
$user = new User();
$user->setId($data['uid']);
$user->setName($data['Name']);
$user->setBirthdate($data['Birth']);
$user->setAge($data['Age']);
$user->setDepart($data['Depart']);
return $user;
}
function createFromDb($userId) {
/* If you need to retrieve data from a database,
* just retrieve them, put in a suited array hash an
* reuse the method we already implemented.
*
* It
*/
$query = "SELECT id as "uid",
username as "Name",
birthday as "Birth",
age as "Age",
department as "Depart"
FROM users
WHERE id = :userid";
$stmt = $this->dbc->prepare($query);
$stmt->bindParam(':userid', $userId, PDO::FETCH_ASSOC);
$stmt->execute();
$data = $stmt->fetch(PDO::FETCH_ASSOC);
return $this->createFromHash($data);
}
}
如何去数据库?
我认为您使用的功能确实存在并且可能已弃用,
只需坚持使用PDO Object 即可使用数据库。
PDO 使用drivers 连接不同的数据库引擎,确保您可以使用通用接口连接到数据库并执行action on the database。
现在是时候把所有东西放在一起了
#Include all the php files you need
// instance $pdo, a PDO object to connect to the database
try{
$factory = new UserFactory();
$user = $factory->createFromHash($_POST);
} catch (InvalidArgumentException $e) {
$user = new User(); // an empty one
}
$page = new HtmlPage();
$contactForm = new UserViewContactForm();
echo $page->render($contactForm->render($user));
您应该已经准备好渲染页面以获取数据。
有一些偷工减料,还有很多工作要在那里获得一个真正有效的解决方案,但我认为这是你可以建立的基础。