Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Weight Conversions Laravel Package

spatie/weight-conversions

Lightweight PHP package for converting between common weight units (e.g., grams, kilograms, pounds, ounces). Handy for apps needing consistent unit handling in calculations, forms, and APIs, with a simple, dependency-free API.

View on GitHub
Deep Wiki
Context7

Getting Started

The spatie/weight-conversions package is a lightweight utility for converting between different weight units (e.g., kilograms, pounds, grams, ounces). To begin, install it via Composer:

composer require spatie/weight-conversions

The package provides a simple facade (Weight) for conversions, eliminating the need for manual calculations. The first use case is straightforward: convert a weight value from one unit to another. For example:

use Spatie\WeightConversions\Facades\Weight;

// Convert 100 grams to kilograms
$kilograms = Weight::grams(100)->toKilograms(); // Returns 0.1

// Convert 5 pounds to kilograms
$kilograms = Weight::pounds(5)->toKilograms(); // Returns ~2.26796

Key starting points:

  • Facade: Use Weight::unit(value) to create a conversion object.
  • Methods: Chain .toUnit() (e.g., toKilograms(), toPounds()) for conversions.
  • Precision: Results are returned as floats with 6 decimal places by default.

Implementation Patterns

Core Workflows

  1. Input Validation: Ensure input values are numeric to avoid runtime errors. Use is_numeric() or Laravel’s floatval() for validation.

    $weight = floatval(request('weight')); // Safely convert user input
    $converted = Weight::kilograms($weight)->toPounds();
    
  2. Dynamic Unit Handling: Store unit types in a database (e.g., unit_type column) and dynamically call the conversion method using app() or a helper:

    $unitType = $product->unit_type; // e.g., 'pounds'
    $converted = Weight::{$unitType}($product->weight)->toKilograms();
    
  3. Batch Conversions: Process arrays of weights efficiently with array_map:

    $weightsInGrams = [100, 200, 300];
    $weightsInKg = array_map(
        fn($g) => Weight::grams($g)->toKilograms(),
        $weightsInGrams
    );
    
  4. API Responses: Normalize responses to a single unit (e.g., kilograms) for consistency:

    return response()->json([
        'weight' => Weight::pounds($product->weight)->toKilograms(),
        'unit' => 'kg'
    ]);
    

Integration Tips

  • Laravel Models: Add accessors to models for seamless conversions:

    public function getWeightInKgAttribute()
    {
        return Weight::{$this->unit_type}($this->weight)->toKilograms();
    }
    
  • Forms: Use the package to validate or transform input data in Form Requests:

    public function rules()
    {
        return [
            'weight' => 'required|numeric',
            'unit' => 'required|in:grams,kilograms,pounds,ounces'
        ];
    }
    
    public function withValidator($validator)
    {
        $validator->after(function ($validator) {
            $weight = Weight::{$this->unit}($this->weight)->toKilograms();
            $validator->errors()->addIf(
                $weight > 1000,
                'weight',
                'Weight cannot exceed 1000 kg.'
            );
        });
    }
    
  • Localization: Combine with Laravel’s localization to display units in user-preferred formats (e.g., "kg" vs. "kilograms").


Gotchas and Tips

Pitfalls

  1. Precision Loss: Floating-point arithmetic can introduce rounding errors. For financial or critical applications, round results explicitly:

    $rounded = round(Weight::ounces(10)->toKilograms(), 3); // 0.283
    
  2. Unit Mismatches: Ensure the input unit matches the method called (e.g., Weight::pounds().toKilograms()). Mixing units without conversion will yield incorrect results.

  3. Negative Values: The package does not validate for negative weights. Handle edge cases in your application logic:

    if ($weight < 0) {
        throw new \InvalidArgumentException('Weight cannot be negative.');
    }
    
  4. Facade vs. Class: While the facade (Weight) is convenient, avoid overusing it in performance-critical paths. Instantiate the class directly for micro-optimizations:

    $converter = new \Spatie\WeightConversions\Weight();
    $result = $converter->pounds(5)->toKilograms();
    

Debugging

  • Unexpected Results: Double-check the conversion direction (e.g., toKilograms() vs. toPounds()). Log intermediate values for debugging:

    $pounds = Weight::kilograms(1)->toPounds();
    \Log::debug("1 kg = {$pounds} lbs");
    
  • Unit Tests: Test edge cases (e.g., zero, maximum values, and rounding):

    public function test_conversion_precision()
    {
        $this->assertEquals(0.453592, Weight::pounds(1)->toKilograms());
        $this->assertEquals(0, Weight::grams(0)->toKilograms());
    }
    

Extension Points

  1. Custom Units: Extend the package by creating a decorator or wrapper for non-standard units (e.g., metric tons). Override the convert() method in a custom class:

    class CustomWeight extends \Spatie\WeightConversions\Weight
    {
        public function toMetricTons()
        {
            return $this->value / 1000;
        }
    }
    
  2. Configuration: While the package lacks a config file, you can define constants or environment variables for default units:

    config(['app.default_weight_unit' => 'kilograms']);
    
  3. Laravel Service Provider: Bind the package to the container for dependency injection:

    $this->app->bind(\Spatie\WeightConversions\Weight::class, function () {
        return new \Spatie\WeightConversions\Weight();
    });
    

Performance

  • Caching: Cache frequent conversions (e.g., static reference weights) if performance is critical:

    $cacheKey = 'weight_conversion_' . md5($value . $fromUnit . $toUnit);
    $converted = Cache::remember($cacheKey, now()->addHours(1), function () use ($value, $fromUnit, $toUnit) {
        return Weight::{$fromUnit}($value)->{$toUnit}();
    });
    
  • Batch Processing: For large datasets, use Laravel’s collect() and map() for lazy evaluation:

    $convertedWeights = collect($weights)->map(function ($weight) {
        return Weight::grams($weight)->toKilograms();
    });
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport