Singleton added

This commit is contained in:
2025-07-03 12:02:19 +03:00
commit 91f8ded888
31 changed files with 5025 additions and 0 deletions

View 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;
}

View 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;
}

View 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;
}
}

View 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
View 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
View 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']);
}