diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml
index b65df91..531c803 100644
--- a/.github/workflows/phpunit.yml
+++ b/.github/workflows/phpunit.yml
@@ -12,19 +12,22 @@ on:
jobs:
Build:
runs-on: 'ubuntu-latest'
- container: 'byjg/php:${{ matrix.php-version }}-cli'
+ container:
+ image: 'byjg/php:${{ matrix.php-version }}-cli'
+ options: --user root --privileged
strategy:
matrix:
php-version:
+ - "8.4"
- "8.3"
- "8.2"
- "8.1"
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- run: composer install
- - run: ./vendor/bin/phpunit
- run: ./vendor/bin/psalm
+ - run: ./vendor/bin/phpunit
Documentation:
if: github.ref == 'refs/heads/master'
@@ -33,5 +36,6 @@ jobs:
with:
folder: php
project: ${{ github.event.repository.name }}
- secrets: inherit
+ secrets:
+ DOC_TOKEN: ${{ secrets.DOC_TOKEN }}
diff --git a/.gitpod.yml b/.gitpod.yml
new file mode 100644
index 0000000..335de09
--- /dev/null
+++ b/.gitpod.yml
@@ -0,0 +1,28 @@
+tasks:
+ - name: Run Composer
+ command: |
+ composer install
+
+image: byjg/gitpod-image:latest
+
+jetbrains:
+ phpstorm:
+ vmoptions: '-Xmx4g'
+ plugins:
+ - com.github.copilot
+ - com.intellij.kubernetes
+ - com.intellij.mermaid
+ - ru.adelf.idea.dotenv
+ - org.toml.lang
+
+vscode:
+ extensions:
+ - ikappas.composer
+ - hbenl.test-adapter-converter
+ - hbenl.vscode-test-explorer
+ - felixfbecker.php-debug
+ - neilbrayfield.php-docblocker
+ - bmewburn.vscode-intelephense-client
+ - getpsalm.psalm-vscode-plugin
+ - SonarSource.sonarlint-vscode
+ - recca0120.vscode-phpunit
\ No newline at end of file
diff --git a/.run/PSalm.run.xml b/.run/PSalm.run.xml
deleted file mode 100644
index bd119ce..0000000
--- a/.run/PSalm.run.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/.run/psalm.run.xml b/.run/psalm.run.xml
new file mode 100644
index 0000000..d9c1b61
--- /dev/null
+++ b/.run/psalm.run.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..a8c1b2a
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,35 @@
+{
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Debug current Script in Console",
+ "type": "php",
+ "request": "launch",
+ "program": "${file}",
+ "cwd": "${fileDirname}",
+ "port": 9003,
+ "runtimeArgs": [
+ "-dxdebug.start_with_request=yes"
+ ],
+ "env": {
+ "XDEBUG_MODE": "debug,develop",
+ "XDEBUG_CONFIG": "client_port=${port}"
+ }
+ },
+ {
+ "name": "PHPUnit Debug",
+ "type": "php",
+ "request": "launch",
+ "program": "${workspaceFolder}/vendor/bin/phpunit",
+ "cwd": "${workspaceFolder}",
+ "port": 9003,
+ "runtimeArgs": [
+ "-dxdebug.start_with_request=yes"
+ ],
+ "env": {
+ "XDEBUG_MODE": "debug,develop",
+ "XDEBUG_CONFIG": "client_port=${port}"
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index 87444ae..fd201df 100644
--- a/README.md
+++ b/README.md
@@ -1,43 +1,86 @@
-# Singleton Pattern
-
-[](https://github.com/byjg/php-singleton-pattern/actions/workflows/phpunit.yml)
-[](http://opensource.byjg.com)
-[](https://github.com/byjg/php-singleton-pattern/)
-[](https://opensource.byjg.com/opensource/licensing.html)
+[](https://github.com/byjg/php-singleton-pattern/actions/workflows/phpunit.yml)
+[](http://opensource.byjg.com)
+[](https://github.com/byjg/php-singleton-pattern/)
+[](https://opensource.byjg.com/opensource/licensing.html)
[](https://github.com/byjg/php-singleton-pattern/releases/)
+# Singleton Pattern
A lightweight PHP implementation of the Design Pattern Singleton using trait.
Just one class and no dependencies.
-## Create your class
+## Requirements
+
+PHP 8.1 or higher
+
+## Installation
+
+```
+composer require "byjg/singleton-pattern"
+```
+
+## Creating a Singleton Class
```php
+someProperty = "Initial value";
+ }
+
+ // Add your own methods and properties here
+ public function doSomething(): void
+ {
+ // Your code here
+ }
}
```
-**REMEMBER:** Your class cannot have a public constructor. If it is necessary, use a private or protected constructor instead.
-Singleton classes does not have arguments in the constructor;
+**IMPORTANT:**
+1. Your class MUST use a private or protected constructor.
+2. Singleton classes do not accept arguments in the constructor.
+3. Attempting to clone, serialize, or unserialize a singleton will throw a `SingletonException`.
-## Use your class
+## Using your Singleton class
```php
+// Get the singleton instance
$example = Example::getInstance();
-```
-## Install
+// The same instance is always returned
+$anotherReference = Example::getInstance();
+$example->someProperty = "Changed value";
+// This will output "Changed value" because both variables reference the same instance
+echo $anotherReference->someProperty;
+
+// This will throw a SingletonException
+try {
+ $cloned = clone $example;
+} catch (\ByJG\DesignPattern\SingletonException $e) {
+ echo "Cannot clone a singleton!";
+}
```
-composer require "byjg/singleton-pattern"
-```
+
+## How It Works
+
+The `Singleton` trait:
+- Implements the `getInstance()` static method to create and manage a single instance
+- Prevents cloning by overriding the `__clone()` method
+- Prevents serialization and deserialization by overriding `__sleep()` and `__wakeup()`
+- Uses a static property to store instances of each class that uses the trait
## Run Tests
@@ -57,4 +100,4 @@ flowchart TD
```
----
-[Open source ByJG](http://opensource.byjg.com)
+[Open source ByJG](http://opensource.byjg.com)
\ No newline at end of file
diff --git a/_config.yml b/_config.yml
deleted file mode 100644
index e3ef350..0000000
--- a/_config.yml
+++ /dev/null
@@ -1,66 +0,0 @@
-name: SingletonPatternPHP
-
-project:
- version: 1.0.0
- download_url: https://github.com/byjg/SingletonPatternPHP/releases
-
-license:
- software: MIT
- software_url: https://opensource.org/licenses/MIT
-
- docs: MIT
- docs_url: https://opensource.org/licenses/MIT
-
-git_edit_address: https://github.com/byjg/SingletonPatternPHP/blob/master/
-
-links:
- header:
- - title: GitHub
- url: https://github.com/byjg/SingletonPatternPHP
- - title: ByJG
- url: https://opensource.byjg.com/
- footer:
- - title: GitHub
- url: https://github.com/byjg/SingletonPatternPHP
- - title: Issues
- url: https://github.com/byjg/SingletonPatternPHP/issues
-
-ui:
- header:
- color1: "#080331"
- color2: "#0033cc"
- trianglify: true
-
-social:
- github:
- user: byjg
- repo: SingletonPatternPHP
- twitter:
- enabled: false
- via:
- hash: opensourcebyjg
- account:
- facebook:
- enabled: true
- url: https://opensource.byjg.com/
- profileUrl:
-
-author:
- twitter: byjg
-
-twitter:
- card: summary
- username: byjg
-
-logo: https://opensource.byjg.com/images/logo_byjg.png
-
-analytics:
- google: UA-130014324-1
-
-plugins:
- - jekyll-seo-tag
-
-# Build settings
-markdown: kramdown
-remote_theme: byjg/jekyll-docs-theme
-
diff --git a/composer.json b/composer.json
index 052ebca..94542c4 100644
--- a/composer.json
+++ b/composer.json
@@ -12,11 +12,15 @@
}
},
"require": {
- "php": ">=8.1 <8.4"
+ "php": ">=8.1 <8.5"
},
"require-dev": {
- "phpunit/phpunit": "^9.6",
- "vimeo/psalm": "^5.9"
+ "phpunit/phpunit": "^10.5|^11.5",
+ "vimeo/psalm": "^5.9|^6.2"
+ },
+ "scripts": {
+ "test": "vendor/bin/phpunit",
+ "psalm": "vendor/bin/psalm"
},
"license": "MIT"
}
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index d5df793..21585f4 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -6,14 +6,17 @@ and open the template in the editor.
-->
-
+ displayDetailsOnTestsThatTriggerDeprecations="true"
+ displayDetailsOnTestsThatTriggerErrors="true"
+ displayDetailsOnTestsThatTriggerNotices="true"
+ displayDetailsOnTestsThatTriggerWarnings="true"
+ displayDetailsOnPhpunitDeprecations="true"
+ stopOnFailure="false"
+ xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd">
@@ -21,11 +24,11 @@ and open the template in the editor.
-
-
- ./src
-
-
+
+
+ ./src/
+
+
diff --git a/psalm.xml b/psalm.xml
index ebabb1a..b208114 100644
--- a/psalm.xml
+++ b/psalm.xml
@@ -4,6 +4,7 @@
resolveFromConfigFile="true"
findUnusedBaselineEntry="true"
findUnusedCode="false"
+ cacheDirectory="/tmp/psalm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
diff --git a/tests/Sample2.php b/tests/Sample2.php
index 02638cd..9e5bbef 100644
--- a/tests/Sample2.php
+++ b/tests/Sample2.php
@@ -9,4 +9,9 @@ class Sample2
use Singleton;
public int $property2;
+
+ private function __construct()
+ {
+ $this->property2 = 20;
+ }
}
diff --git a/tests/SingletonTest.php b/tests/SingletonTest.php
index 1f3fe10..c931b64 100644
--- a/tests/SingletonTest.php
+++ b/tests/SingletonTest.php
@@ -7,7 +7,7 @@
class SingletonTest extends TestCase
{
- public function testSingleton()
+ public function testSingleton(): void
{
$sample1 = Sample1::getInstance();
$this->assertEquals(10, $sample1->property);
@@ -37,14 +37,14 @@ public function testSingleton()
$this->assertEquals(40, $sample1->property);
}
- public function testClone()
+ public function testClone(): void
{
$this->expectException(SingletonException::class);
$sample1 = Sample1::getInstance();
$sample2 = clone $sample1;
}
- public function testSerialize()
+ public function testSerialize(): void
{
$this->expectException(SingletonException::class);
$sample1 = Sample1::getInstance();