Понятно, что "по феншую" надо вывести универсальный набор параметров, подходящий для любой логики
обеспечить возможность настройки любой новой логики для нового перевозчика "из админки", без вмешательства в код
при этом соблюсти безопасность при выполнении этого кода
наверняка, есть какие-то готовые инструменты для подобной задачи
А на что еще стоит посмотреть?
в каком месте нужно закрывать соединение с БД?
В каждом методе?
// Не давайте общие имена конкретным реализациям
// Почитайте, проникнитесь и используйте PSR-2 и PSR-4
class DataBase
{
private $mysqli;
private $dbConfig;
public function __construct()
{
// Класс по работе с БД не должен знать даже о существовании неких файлов, где-то там. Это не его забота.
// Передавайте в конструктор готовое подключение к БД, если нужно.
$this->dbConfig = require "db/database_config.php";
// Вот никак понять не могу, за что так любят этот mysqli, ну что в нем прям такого раз такого, по сравнению с PDO?
$this->mysqli = mysqli_connect($this->dbConfig['host'], $this->dbConfig['username'], $this->dbConfig['password'], $this->dbConfig['db_name']);
// Почему вдруг класс по работе с БД занимается операцией вывода?
// Если что-то не так - бросайте исключение, ни каких echo, die, exit, trigger_error
if (mysqli_connect_errno($this->mysqli)) {
echo "Не удалось подключиться к MySQL: " . mysqli_connect_error();
}
}
// Вы не проверяете аргументы, это плохо, очень.
// Что бы нагнуть ваш проект достаточно передать в любой из аргументов: '1; DROP TABLE employees;'
public function getEmployees($where='1',$start, $perPage){
// ЗАБУДЬТЕ про подстановку данных через конкатенацию, используйте плейсхолдеры
// http://php.net/manual/ru/pdo.prepared-statements.php
$sql="SELECT e.name,e.birthday,d.title_dep,p.title_pos,t.title_type,e.salary FROM `employees` AS e INNER JOIN departments AS d ON e.id_dep=d.id
INNER JOIN positions AS p ON e.id_pos=p.id
INNER JOIN payment_types AS t ON e.id_type=t.id where $where LIMIT $start,$perPage";
// Вам ни переменная $res, ни $row не нужны
$res = $this->mysqli->query($sql);
$row=$res->fetch_all(MYSQLI_ASSOC);
return $row;
}
}
use Symfony\Component\HttpFoundation\Request;
class LoginForm
{
/** @var string */
private $login;
/** @var string */
private $password;
/**
* @param Request $request
*/
public function __construct(Request $request)
{
$login = $request->request->get('login');
$password = $request->request->get('password');
if (is_null($login)) {
throw new \InvalidArgumentException('Parameter "login" is required');
} elseif (!is_string($login)) {
throw new \InvalidArgumentException('Parameter "login" must be string');
} elseif (strlen($login) < 3) {
throw new \InvalidArgumentException('Length of parameter "login" must be greater than 3');
} elseif (strlen($login) > 64) {
throw new \InvalidArgumentException('Length of parameter "login" must be less than 64');
} elseif (preg_match('/^[a-z\d]+$/i', $login) === 0) {
throw new \InvalidArgumentException('Parameter "login" contain not allowed symbols');
}
if (is_null($password)) {
throw new \InvalidArgumentException('Parameter "password" is required');
} elseif (!is_string($password)) {
throw new \InvalidArgumentException('Parameter "password" must be string');
} elseif (strlen($password) < 6) {
throw new \InvalidArgumentException('Length of parameter "password" must be greater than 6');
}
$this->login = $login;
$this->password = $password;
}
/**
* @return string
*/
public function getLogin(): string
{
return $this->login;
}
/**
* @return string
*/
public function getPassword(): string
{
return $this->password;
}
}
// Используйте PSR-2. Стандарт оформления кода не просто так придуман.
// Кстати, это MySQL БД, или PostgreSQL, или sqlite? Не стоит давать общие имена для конкретных реализаций.
class DataBase {
// Достаточно такого:
// /** @var \PDO */
// private $connection;
private $connectDataBase;
// конструкция подключения к БД
function __construct () {
// Вот никак не могу понять, чего народ так упорно mysqli любит, ну что там такого прям раз такого, по сравнению с PDO?
// Передавайте готовое подключение в конструктор, а не создавайте его там.
$this->connectDataBase = new mysqli(DB_HOST, DB_USERNAME, DB_PASSWORD, DB_DATABASE);
if ($this->connectDataBase->connect_errno) {
// С какого класс по работе с БД управляет процессом и выводом? Если что-то пошло не так - бросайте исключение. Конструкцию die - забудьте.
die('Connect Error (' . $this->connectDataBase->connect_errno . ') ' . $this->connectDataBase->connect_error);
}
}
// Не пишите бесполезных комментариев
// метод подготовленного запроса к базе
function query ($sql) {
// Зачем вам переменная $result?
$result = $this->connectDataBase->query($sql);
return $result;
}
}
разве Composer не должен автоматически это делать?
Но вопрос в том что все это по сути не имеет смысла потому что при каждом запросе к серверу будет заново создаваться синглтон
Возможно ли как то изменить это поведение или хотя бы закэшировать данные?
У меня в xml файле хранятся какие-то настройки.
Самый логичный способ использовать для такой цели статический класс или синглтон.
// Я надеюсь вы знаете про PSR4 и символ подчеркивания тут случайно
class MV_Files
{
// PSR2: методы пишутся в lowerCamelCase
// Нет проверки аргументов. что произойдет, если $name будет массивом?
// Не ясно, на кой вам тут возврат bool? Если что-то не так - бросайте исключение.
public function CreateFile($path, $name, $right = 0777)
{
if (!file_exists($path . '/' . $name)) {
// Посмотрите http://php.net/manual/ru/function.touch.php
fclose(fopen($path . '/' . $name, 'w'));
chmod($path . '/' . $name, $right);
// PSR2: Перед return перевод строки
return true;
// Не ясно, зачем вам тут else?
} else {
return false;
}
}
// PSR2: методы пишутся в lowerCamelCase
// Нет проверки аргументов. что произойдет, если $name будет массивом?
// Не ясно, на кой вам тут возврат bool? Если что-то не так - бросайте исключение.
public function CreateFileContent($path, $name, $text, $right = 0777)
{
if (!file_exists($path . '/' . $name)) {
// file_put_contents, не?
$file = fopen($path . '/' . $name, 'w');
fwrite($file, $text);
fclose($file);
chmod($path . '/' . $name, $right);
// PSR2: Перед return перевод строки
return true;
// Не ясно, зачем вам тут else?
} else {
return false;
}
}
// PSR2: методы пишутся в lowerCamelCase
// Нет проверки аргументов. что произойдет, если $path будет массивом?
// Не ясно, на кой вам тут возврат bool? Если что-то не так - бросайте исключение.
public function AddFileContent($path, $text)
{
if (file_exists($path)) {
// file_put_contents($path, $content, FILE_APPEND)
$file = fopen($path, 'a');
fwrite($file, $text);
fclose($file);
// PSR2: Перед return перевод строки
return true;
// Не ясно, зачем вам тут else?
} else {
return false;
}
}
// PSR2: методы пишутся в lowerCamelCase
// Нет проверки аргументов. что произойдет, если $path будет массивом?
// Не ясно, на кой вам тут возврат bool? Если что-то не так - бросайте исключение.
public function OverwriteFileContent($path, $text)
{
if (file_exists($path)) {
// file_put_contents($path, $content)
$file = fopen($path, 'w');
fwrite($file, $text);
fclose($file);
// PSR2: Перед return перевод строки
return true;
// Не ясно, зачем вам тут else?
} else {
return false;
}
}
// PSR2: методы пишутся в lowerCamelCase
// Нет проверки аргументов. что произойдет, если $oldname будет массивом?
// Не ясно, на кой вам тут возврат bool? Если что-то не так - бросайте исключение.
// Чего вдруг метод статический?
public static function RenameFile($oldname, $newname) {
if (file_exists($oldname)) {
return rename($oldname, $newname);
} else {
return false;
}
}
// PSR2: методы пишутся в lowerCamelCase
// Нет проверки аргументов. что произойдет, если $path будет массивом?
// Не ясно, на кой вам тут возврат bool? Если что-то не так - бросайте исключение.
public function DeleteFile($path)
{
if (file_exists($path)) {
return unlink($path);
} else {
return false;
}
}
// Нет проверки аргументов. что произойдет, если $path будет массивом?
// Не ясно, на кой вам тут возврат bool? Если что-то не так - бросайте исключение.
public function getFileContent($path)
{
if (file_exists($path)) {
return file_get_contents($path);
} else {
return false;
}
}
// Нет проверки аргументов. что произойдет, если $path будет массивом?
// Не ясно, на кой вам тут возврат bool? Если что-то не так - бросайте исключение.
// "size" обычно трактуется как число, а не форматированная строка.
public function getFileSize($path)
{
if (file_exists($path)) {
// Конструкция - гавно)). Если хотите интовый $size - то сохраняйте в него инт
(int)$size = filesize($path);
switch (true) {
case $size >= 1073741824:
$size = round($size / 1073741824 * 100) / 100 . ' GB';
break;
case $size >= 1048576:
$size = round($size / 1048576 * 100) / 100 . ' MB';
break;
case $size >= 1024:
$size = round($size / 1024 * 100) / 100 . ' KB';
break;
default:
$size .= ' Bytes';
break;
}
return $size;
} else {
return false;
}
}
// Нет проверки аргументов. что произойдет, если $path будет массивом?
// Не ясно, на кой вам тут возврат bool? Если что-то не так - бросайте исключение.
// Прочитайте http://php.net/manual/ru/class.splfileinfo.php
public function getFileInfo($path)
{
if (file_exists($path)) {
return pathinfo($path);
} else {
return false;
}
}
// Нет проверки аргументов. что произойдет, если $dirname будет массивом?
// Прочитайте http://php.net/manual/ru/class.directoryiterator.php
public function getFileList($dirname)
{
$dir = array_diff(scandir($dirname), ['.', '..']);
$files = [];
// Рекомендую перед управляющими конструкциями делать перевод строки, так читать проще
foreach ($dir as $value) {
if (is_file($value)) {
$files[] = $value;
}
}
// PSR2: перед return перевод строки
return $files;
}
// Лишний перевод строки
}
А если мне нужно написать модуль регистрации пользователя? Как здесь быть?