Singleton added
This commit is contained in:
17
src/Contracts/Loggable.php
Normal file
17
src/Contracts/Loggable.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package: patterns
|
||||
* @author: Yevhen Odynets
|
||||
* @date: 2025-07-03
|
||||
* @time: 07:36
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Contracts;
|
||||
|
||||
interface Loggable
|
||||
{
|
||||
public static function getInstance(): static;
|
||||
}
|
||||
17
src/Contracts/SingleInterface.php
Normal file
17
src/Contracts/SingleInterface.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package: patterns
|
||||
* @author: Yevhen Odynets
|
||||
* @date: 2025-07-03
|
||||
* @time: 10:58
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Contracts;
|
||||
|
||||
interface SingleInterface
|
||||
{
|
||||
public function childish(): void;
|
||||
}
|
||||
105
src/Pattern/Creational/Singleton.php
Normal file
105
src/Pattern/Creational/Singleton.php
Normal file
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package: patterns
|
||||
* @author: Yevhen Odynets
|
||||
* @date: 2025-07-03
|
||||
* @time: 07:00
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Pattern\Creational;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* The Singleton class defines the `GetInstance` method that serves as an
|
||||
* alternative to constructor and lets clients access the same instance of this
|
||||
* class over and over.
|
||||
*/
|
||||
class Singleton
|
||||
{
|
||||
/**
|
||||
* The Singleton's instance is stored in a static field. This field is an
|
||||
* array, because we'll allow our Singleton to have subclasses. Each item in
|
||||
* this array will be an instance of a specific Singleton's subclass. You'll
|
||||
* see how this works in a moment.
|
||||
*/
|
||||
private static array $instances = [];
|
||||
|
||||
public ?string $value = null;
|
||||
|
||||
/**
|
||||
* The Singleton's constructor should always be private to prevent direct
|
||||
* construction calls with the `new` operator.
|
||||
*/
|
||||
protected function __construct() {}
|
||||
|
||||
/**
|
||||
* This is the static method that controls the access to the singleton
|
||||
* instance. On the first run, it creates a singleton object and places it
|
||||
* into the static field. On subsequent runs, it returns the client existing
|
||||
* object stored in the static field.
|
||||
*
|
||||
* This implementation lets you subclass the Singleton class while keeping
|
||||
* just one instance of each subclass around.
|
||||
*/
|
||||
public static function getInstance(?string $message = null): Singleton
|
||||
{
|
||||
$cls = static::class;
|
||||
|
||||
/** @noinspection ForgottenDebugOutputInspection */
|
||||
dump(trim($message . ': ' . $cls, ' :'));
|
||||
|
||||
if (!isset(self::$instances[$cls])) {
|
||||
self::$instances[$cls] = new static();
|
||||
}
|
||||
|
||||
return self::$instances[$cls];
|
||||
}
|
||||
|
||||
/**
|
||||
* Singletons should not be restorable from strings.
|
||||
*/
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new RuntimeException("Cannot unserialize a singleton.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Finally, any singleton should define some business logic, which can be
|
||||
* executed on its instance.
|
||||
*/
|
||||
public function someBusinessLogic(): void
|
||||
{
|
||||
echo 'I AM SINGLETON: ' . date('H:i:s') . '<br>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Singletons should not be cloneable.
|
||||
*/
|
||||
protected function __clone() {}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getValue(): ?string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setValue(?string $value): static
|
||||
{
|
||||
$this->value = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
24
src/Pattern/Creational/Sub/Single.php
Normal file
24
src/Pattern/Creational/Sub/Single.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package: patterns
|
||||
* @author: Yevhen Odynets
|
||||
* @date: 2025-07-03
|
||||
* @time: 10:22
|
||||
*/
|
||||
|
||||
//phpcs:ignore
|
||||
declare(strict_types = 1);
|
||||
namespace Pattern\Creational\Sub;
|
||||
|
||||
use Contracts\SingleInterface;
|
||||
use Pattern\Creational\Singleton;
|
||||
|
||||
class Single extends Singleton implements SingleInterface
|
||||
{
|
||||
public function childish(): void
|
||||
{
|
||||
/** @noinspection ForgottenDebugOutputInspection */
|
||||
dump(__METHOD__);
|
||||
}
|
||||
}
|
||||
136
src/Service/Logger.php
Normal file
136
src/Service/Logger.php
Normal file
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package: patterns
|
||||
*
|
||||
* @author: Yevhen Odynets
|
||||
*
|
||||
* @date: 2025-07-02
|
||||
*
|
||||
* @time: 22:30
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Service;
|
||||
|
||||
use Contracts\Loggable;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use RuntimeException;
|
||||
|
||||
use function in_array;
|
||||
use function sprintf;
|
||||
|
||||
use const FILE_APPEND;
|
||||
use const PHP_EOL;
|
||||
|
||||
class Logger implements Loggable
|
||||
{
|
||||
public const string LOG_FILE = '../storage/logs/main.txt';
|
||||
public const array ALLOWED_LOG_TYPES
|
||||
= [
|
||||
'file',
|
||||
'error_log',
|
||||
];
|
||||
private static ?Logger $instance = null;
|
||||
private ?string $logType = null;
|
||||
private ?string $dateFormat = null;
|
||||
private ?string $prefix = null;
|
||||
|
||||
private function __construct() {}
|
||||
|
||||
public static function getInstance(): static
|
||||
{
|
||||
if (self::$instance) {
|
||||
self::$instance = new static();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
public function getLogType(): string
|
||||
{
|
||||
if (! $this->logType) {
|
||||
throw new RuntimeException('log type is null');
|
||||
}
|
||||
|
||||
return $this->logType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setLogType(string $logType): static
|
||||
{
|
||||
if (! in_array($logType, self::ALLOWED_LOG_TYPES)) {
|
||||
throw new RuntimeException('undefined log type: ' . $logType);
|
||||
}
|
||||
|
||||
$this->logType = $logType;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function log(string $data): void
|
||||
{
|
||||
$prefix = $this->getPrefix();
|
||||
|
||||
$message = sprintf(
|
||||
'%s: %s%s',
|
||||
date($this->getDateFormat()),
|
||||
empty($prefix) ? '' : $prefix . ' ',
|
||||
$data . PHP_EOL
|
||||
);
|
||||
|
||||
if ('file' === $this->logType) {
|
||||
file_put_contents(self::LOG_FILE, $message, FILE_APPEND);
|
||||
} elseif ('error_log' === $this->logType) {
|
||||
/* @noinspection ForgottenDebugOutputInspection */
|
||||
error_log($message, 3, self::LOG_FILE);
|
||||
}
|
||||
}
|
||||
|
||||
public function getPrefix(): ?string
|
||||
{
|
||||
return $this->prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setPrefix(?string $prefix): static
|
||||
{
|
||||
$this->prefix = $prefix;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDateFormat(): string
|
||||
{
|
||||
if (! $this->dateFormat) {
|
||||
throw new RuntimeException('date format is null');
|
||||
}
|
||||
|
||||
return $this->dateFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setDateFormat(string $dateFormat): static
|
||||
{
|
||||
$this->dateFormat = $dateFormat;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function __clone() {}
|
||||
}
|
||||
|
||||
|
||||
///*$message = 'Message from delivery service';
|
||||
//
|
||||
//$logger = new Logger();
|
||||
//$dateFormat = 'Y-m-d H:i:s' . (preg_match('/^win/i', PHP_OS) ? '' : '.u');
|
||||
//$logger->setDateFormat($dateFormat)->setLogType('error_log');
|
||||
//$logger->log($message);*/
|
||||
36
src/helpers.php
Normal file
36
src/helpers.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package: patterns
|
||||
* @author: Yevhen Odynets
|
||||
* @date: 2025-07-03
|
||||
* @time: 09:07
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
/**
|
||||
* @param ...$vars
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function dump(...$vars): void
|
||||
{
|
||||
echo '<pre><code class="language-stylus">';
|
||||
var_dump(...$vars);
|
||||
echo '</code></pre>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function trace(): string
|
||||
{
|
||||
$traced = debug_backtrace();
|
||||
|
||||
// Maybe this is useless, but anyway...
|
||||
$offset = __FUNCTION__ === $traced[0]['function'] ? 1 : 0;
|
||||
$traced = $traced[$offset];
|
||||
|
||||
return sprintf('%s@%s:%d', $traced['function'], $traced['file'], $traced['line']);
|
||||
}
|
||||
Reference in New Issue
Block a user