Weave 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

Distance Laravel Package

frost/distance

PHP distance conversion library for US and metric units. Convert between mi, ft, in, km, m, cm, and mm (US↔metric, US↔US, metric↔metric). Simple fluent API: setUnit(), setDistance(), convertTo().

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require frost/distance
    

    Add to composer.json if not using autoloading:

    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "Frost\\": "vendor/frost/distance/src/"
        }
    }
    

    Run composer dump-autoload.

  2. First Use Case: Convert a distance in kilometers to miles in a Laravel controller:

    use Frost\Distance;
    
    $converter = new Distance();
    $miles = $converter->setUnit('km')->setDistance(10)->convertTo('mi');
    return response()->json(['distance' => $miles]);
    
  3. Key Files:

    • vendor/frost/distance/src/Distance.php (Main class)
    • vendor/frost/distance/src/Unit.php (Unit definitions)

Implementation Patterns

Core Workflow

  1. Chaining for Readability:

    $distance = (new Distance())
        ->setUnit('m')
        ->setDistance(1000)
        ->convertTo('ft');
    
  2. Service Provider (Recommended for Reusability): Register in config/app.php:

    'providers' => [
        // ...
        Frost\DistanceServiceProvider::class,
    ],
    

    Bind in DistanceServiceProvider.php:

    public function register()
    {
        $this->app->singleton(Distance::class, function ($app) {
            return new Distance();
        });
    }
    

    Use via dependency injection:

    public function __construct(private Distance $distance) {}
    
  3. Laravel Facade (Optional): Extend the package to create a facade (e.g., DistanceFacade):

    // app/Providers/DistanceServiceProvider.php
    public function boot()
    {
        Distance::setFacadeApplication($this->app);
    }
    

    Use in views/controllers:

    use Frost\Facades\Distance;
    
    $feet = Distance::setUnit('km')->setDistance(5)->convertTo('ft');
    
  4. Form Request Validation: Validate distance inputs in Laravel requests:

    public function rules()
    {
        return [
            'distance' => 'required|numeric|min:0',
            'from_unit' => 'required|in:mi,ft,in,km,m,cm,mm',
            'to_unit' => 'required|in:mi,ft,in,km,m,cm,mm',
        ];
    }
    
  5. Model Observers/Accessors: Add distance conversion to Eloquent models:

    // app/Models/Product.php
    public function getConvertedDistanceAttribute()
    {
        return (new Distance())
            ->setUnit($this->unit)
            ->setDistance($this->distance)
            ->convertTo('km'); // Default to metric
    }
    

Gotchas and Tips

Pitfalls

  1. Floating-Point Precision:

    • Conversions like mm to mi may yield unexpected decimal results (e.g., 1609344 mm = 1.0000000000000002 mi).
    • Fix: Round results explicitly:
      $miles = round($distance->convertTo('mi'), 6);
      
  2. Unit Case Sensitivity:

    • The library expects lowercase units (e.g., 'km', not 'KM').
    • Fix: Normalize inputs:
      $unit = strtolower($request->input('unit'));
      
  3. Unsupported Units:

    • Only mi, ft, in, km, m, cm, mm are supported. Custom units (e.g., nautical miles) will throw errors.
    • Fix: Extend the Unit class or validate inputs:
      $validUnits = ['mi', 'ft', 'in', 'km', 'm', 'cm', 'mm'];
      if (!in_array($unit, $validUnits)) {
          throw new \InvalidArgumentException("Unit {$unit} not supported.");
      }
      
  4. Zero Division Edge Cases:

    • Converting 0 to any unit works, but dividing by zero in intermediate steps (e.g., cm to mi) could theoretically occur if the library logic changes.
    • Fix: Add input validation for zero distances:
      if ($distance->setDistance(-1)->convertTo('mi')) {
          throw new \InvalidArgumentException("Distance cannot be negative.");
      }
      

Debugging Tips

  1. Log Conversion Steps: Add debug output to trace conversions:

    $distance->setUnit('cm')->setDistance(150000);
    $miles = $distance->convertTo('mi');
    \Log::debug("Conversion: {$distance->getDistance()} {$distance->getUnit()} = {$miles} mi");
    
  2. Unit Tests: Write tests for critical conversions:

    // tests/Unit/DistanceTest.php
    public function testKmToMiles()
    {
        $this->assertEquals(0.621371, (new Distance())
            ->setUnit('km')->setDistance(1)->convertTo('mi'), null, 0.000001);
    }
    

Extension Points

  1. Add Custom Units: Extend the Unit class to support additional units (e.g., nautical miles):

    // app/Extensions/CustomUnit.php
    namespace App\Extensions;
    
    use Frost\Unit;
    
    class CustomUnit extends Unit
    {
        public static function getNauticalMilesToMeters()
        {
            return 1852;
        }
    }
    

    Register in a service provider:

    Unit::addUnit('nm', 'nautical miles', CustomUnit::class);
    
  2. Caching Conversions: Cache frequent conversions (e.g., API responses) using Laravel's cache:

    $cacheKey = "distance_{$from}_{$to}_{$distance}";
    $converted = \Cache::remember($cacheKey, now()->addHours(1), function () use ($distance, $from, $to) {
        return $distance->setUnit($from)->setDistance($distance)->convertTo($to);
    });
    
  3. Laravel Scout Integration: Use distance conversions for geospatial search (e.g., "find locations within 10 km"):

    $user = User::where('latitude', '<=', $currentLat + 10)
        ->where('latitude', '>=', $currentLat - 10)
        ->where('longitude', '<=', $currentLon + (10 / 69)) // Approx. conversion
        ->where('longitude', '>=', $currentLon - (10 / 69))
        ->first();
    

    Replace with precise conversions using the library for accuracy.

  4. API Resource Formatting: Format distance responses in API resources:

    // app/Http/Resources/DistanceResource.php
    public function toArray($request)
    {
        return [
            'value' => $this->distance,
            'unit' => $this->unit,
            'converted' => [
                'miles' => (new Distance())
                    ->setUnit($this->unit)
                    ->setDistance($this->distance)
                    ->convertTo('mi'),
                'kilometers' => (new Distance())
                    ->setUnit($this->unit)
                    ->setDistance($this->distance)
                    ->convertTo('km'),
            ],
        ];
    }
    
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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core