1. Go to this page and download the library: Download azaharizaman/nexus-common library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
use Nexus\Common\ValueObjects\Measurement;
use Nexus\Common\ValueObjects\Quantity;
use Nexus\Common\ValueObjects\UnitOfMeasurement;
// Measurement with conversions
$weight = Measurement::of(2.5, UnitOfMeasurement::KG);
$weightInGrams = $weight->convertTo(UnitOfMeasurement::G); // 2500 g
$weightInPounds = $weight->convertTo(UnitOfMeasurement::LB); // ~5.51 lb
// Arithmetic with auto-conversion
$weight1 = Measurement::of(1000, UnitOfMeasurement::G);
$weight2 = Measurement::of(1, UnitOfMeasurement::KG);
$total = $weight1->add($weight2); // 2000 g (auto-converts to common unit)
// Check conversion compatibility
if ($weight->canConvertTo(UnitOfMeasurement::G)) {
$converted = $weight->convertTo(UnitOfMeasurement::G);
}
// Quantity for inventory
$stock = Quantity::of(100, UnitOfMeasurement::PCS);
$shipped = Quantity::of(25, UnitOfMeasurement::PCS);
$remaining = $stock->subtract($shipped); // 75 pcs
if ($remaining->isZero()) {
echo "Out of stock";
}
use Nexus\Common\ValueObjects\CustomerId;
use Nexus\Common\ValueObjects\ProductId;
// Generate new IDs (ULID-based)
$customerId = CustomerId::generate();
$productId = ProductId::generate();
// Type safety prevents mixing
function processOrder(CustomerId $customerId, ProductId $productId) {
// Can't accidentally pass ProductId where CustomerId is expected
// PHP type system enforces this at compile time
}
// From string (e.g., from database)
$id = CustomerId::fromString('01HN6Z8Y9C3EXAMPLE123');
// Serialization
$idString = $customerId->toString();
$ulid = $customerId->toUlid(); // Returns Symfony\Component\Uid\Ulid
// Comparison
if ($customerId->equals($otherCustomerId)) {
echo "Same customer";
}
use Nexus\Common\ValueObjects\Email;
use Nexus\Common\ValueObjects\PhoneNumber;
use Nexus\Common\ValueObjects\Address;
// Email validation (RFC 5322)
try {
$email = Email::of('[email protected]');
$domain = $email->getDomain(); // "example.com"
$local = $email->getLocalPart(); // "customer"
} catch (InvalidValueException $e) {
// Invalid email format
}
// Phone number formatting (E.164)
$phone = PhoneNumber::of('+60123456789');
$countryCode = $phone->getCountryCode(); // "+60"
$formatted = $phone->format(); // "+60 12-345 6789"
// Address with ISO country codes
$address = Address::of(
street: '123 Main Street',
street2: 'Suite 100',
city: 'Kuala Lumpur',
state: 'Federal Territory',
postalCode: '50000',
country: 'MY' // ISO 3166-1 alpha-2
);
$full = $address->getFullAddress(); // Complete formatted address
use Nexus\Common\ValueObjects\DateRange;
// Create date range
$fiscalPeriod = DateRange::of(
startDate: new DateTimeImmutable('2024-01-01'),
endDate: new DateTimeImmutable('2024-12-31')
);
// Check if date is within range
$isInPeriod = $fiscalPeriod->contains(
new DateTimeImmutable('2024-06-15')
); // true
// Check overlaps
$q1 = DateRange::of(
new DateTimeImmutable('2024-01-01'),
new DateTimeImmutable('2024-03-31')
);
$overlaps = $fiscalPeriod->overlaps($q1); // true
// Time adjustments
$extended = $fiscalPeriod->extend(days: 30); // Extends end date
$shifted = $fiscalPeriod->shift(months: 1); // Shifts both dates
// Get duration
$days = $fiscalPeriod->getDays(); // 366 (2024 is leap year)
// Check if currently active
if ($fiscalPeriod->isActive()) {
echo "Period is active";
}
use Nexus\Common\ValueObjects\TaxRate;
use Nexus\Common\ValueObjects\TaxCode;
use Nexus\Common\ValueObjects\Percentage;
// Tax rate with temporal validity
$taxRate = TaxRate::of(
rate: Percentage::of(6.0),
taxType: 'SST',
jurisdiction: 'MY',
effectiveFrom: new DateTimeImmutable('2024-01-01'),
effectiveTo: new DateTimeImmutable('2024-12-31')
);
// Check if rate is valid on specific date
$date = new DateTimeImmutable('2024-06-15');
if ($taxRate->isEffectiveOn($date)) {
$taxAmount = $taxRate->calculateTax(amountInMinorUnits: 100000);
// RM 1000 -> RM 60 tax
}
// Tax code system
$taxCode = TaxCode::of(
code: 'TX',
description: 'Standard Rate',
rate: Percentage::of(6.0),
isActive: true
);
if ($taxCode->isActive()) {
$tax = $taxCode->calculateTax(amountInMinorUnits: 50000);
// RM 500 -> RM 30 tax
}
use Nexus\Common\ValueObjects\Status;
// Factory methods for common states
$draft = Status::draft();
$pending = Status::pending();
$approved = Status::approved();
$rejected = Status::rejected();
$closed = Status::closed();
// Check allowed transitions
if ($draft->canTransitionTo($pending)) {
$newStatus = $draft->transitionTo($pending);
echo $newStatus->getState(); // "pending"
}
// Prevent invalid transitions
try {
$draft->transitionTo($approved); // Draft -> Approved not allowed
} catch (InvalidValueException $e) {
echo "Invalid state transition";
}
// Check if final state
if ($approved->isFinal()) {
echo "No further transitions allowed";
}
// Custom workflow
$customStatus = Status::of(
state: 'in_review',
allowedTransitions: ['approved', 'rejected'],
isFinal: false
);
use Nexus\Common\ValueObjects\VarianceResult;
// Create variance result
$result = VarianceResult::of(
actual: 95000.0,
budget: 100000.0
);
// Get variance (computed property)
$variance = $result->getVariance(); // -5000.0
$percentage = $result->getPercentageVariance(); // -5.0%
// Business analysis
if ($result->isUnfavorable()) {
echo "Actual is below budget (unfavorable)";
}
if ($result->isFavorable()) {
echo "Actual exceeds budget (favorable)";
}
// Statistical operations
$results = [
VarianceResult::of(95000, 100000),
VarianceResult::of(105000, 100000),
VarianceResult::of(98000, 100000),
];
$average = VarianceResult::average($results);
// Trend analysis
$lastMonth = VarianceResult::of(90000, 100000);
$thisMonth = VarianceResult::of(95000, 100000);
$trend = $thisMonth->getTrendDirection($lastMonth); // 'up'
$change = $thisMonth->percentageChange($lastMonth); // 5.56%
if ($thisMonth->isSignificantChange($lastMonth, threshold: 0.10)) {
echo "Significant variance change detected (>10%)";
}
// Range validation
$minResult = VarianceResult::of(80000, 100000);
$maxResult = VarianceResult::of(120000, 100000);
if ($result->isWithinRange($minResult, $maxResult)) {
echo "Result is within acceptable range";
}
// Arithmetic operations
$combined = $result->add($lastMonth); // Combines actual and budget
$adjusted = $result->multiply(1.1); // Scale by 110%
use Nexus\Common\ValueObjects\TenantId;
// Create a new TenantId
$tenantId = TenantId::generate();
// Create from existing ULID string
$tenantId = TenantId::fromString('01ARZ3NDEKTSV4RRFFQ69G5FAV');
// Compare tenant IDs
if ($tenantId->equals($otherTenantId)) {
echo "Same tenant";
}
// Get string value
$tenantIdString = $tenantId->toString();
use Nexus\Common\Contracts\ClockInterface;
final readonly class MyService
{
public function __construct(
private ClockInterface $clock
) {}
public function isExpired(\DateTimeImmutable $expiresAt): bool
{
return $expiresAt < $this->clock->now();
}
}
use Psr\Log\LoggerInterface;
final readonly class MyService
{
public function __construct(
private LoggerInterface $logger
) {}
public function doSomething(): void
{
$this->logger->info('Operation completed', [
'context' => 'additional data'
]);
}
}
$money = Money::of(100, 'MYR');
$newMoney = $money->add(Money::of(50, 'MYR')); // Returns new instance
// $money still contains 100, $newMoney contains 150
// Type system prevents mixing different entity IDs
function processOrder(CustomerId $customerId, ProductId $productId) {
// Can't pass ProductId where CustomerId is expected
}
// ✅ GOOD: Defines behavior
interface Addable {
public function add(self $other): static;
}
// ❌ BAD: Just a marker (not used in this package)
interface ValueObjectInterface {
// No methods - just marks a class
}
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.