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

Openweathermap Php Api Laravel Package

cmfcmf/openweathermap-php-api

A lightweight, object-oriented PHP wrapper for OpenWeatherMap. Retrieve current weather, forecasts, and historical data by city name, coordinates, or city ID, with configurable units and language. Simple setup and clean response objects.

Deep Wiki
Context7

Getting Started

Install the package and a PSR-18 HTTP client (the library discovers one automatically, but installing it explicitly avoids surprise runtime errors):

composer require cmfcmf/openweathermap-php-api guzzlehttp/guzzle

Get an API key from OpenWeatherMap, put it in .env (never in code), and make the smallest possible call. The first useful use case is a current-conditions widget:

use Cmfcmf\OpenWeatherMap;

$owm = new OpenWeatherMap($_ENV['OWM_API_KEY']);

try {
    $weather = $owm->getWeather('Berlin', 'metric', 'en');

    printf(
        "%s: %s (%s)\n",
        $weather->city->name,
        $weather->temperature->now,          // __toString on the unit object
        $weather->weather->description
    );
} catch (\Cmfcmf\OpenWeatherMap\Exception $e) {
    // invalid key, unknown city, quota exceeded, etc.
    error_log($e->getMessage());
}

Where to look first:

  • src/OpenWeatherMap.php — the public façade; all supported endpoints are methods here.
  • src/Query/ — one class per endpoint (CurrentWeatherQuery, ForecastQuery, etc.); this is where parsing lives if a field is missing.
  • src/Util/ — the value objects you actually consume: Unit, Temperature, Wind, Pressure, Humidity, Sun, City, Coordinates.
  • The README examples are the fastest reference for method names; check the installed version because several methods were renamed between 1.x and 2.x.

A minimal first call is enough to prove key, client discovery, and network egress all work before you build caching or UI around it.

Implementation Patterns

Wrap the façade in one application service. Bind a single configured instance and never scatter new OpenWeatherMap(...) through controllers. In Laravel:

// AppServiceProvider::register()
$this->app->singleton(OpenWeatherMap::class, function () {
    return new OpenWeatherMap(config('services.openweather.key'));
});

Then inject OpenWeatherMap into a small WeatherService that applies your defaults (units, language, coordinate convention). This gives you one place to later add caching, retries, and logging.

Use coordinates or city IDs, not city names, for anything automated. City strings are ambiguous and can resolve to an unexpected place. Keep a Coordinates value object or OWM city ID in your database:

use Cmfcmf\OpenWeatherMap\Util\Coordinates;

$weather = $owm->getWeather(new Coordinates(52.5200, 13.4050), 'metric', 'en');

Treat forecast as a 3-hourly stream, then aggregate for UI. The free forecast endpoint returns ~40 entries over five days. Daily highs/lows must be computed client-side:

$daily = [];
foreach ($owm->getForecast($coordinates, 'metric', 'en') as $point) {
    $day = $point->time->format('Y-m-d');
    $temp = $point->temperature->now->getValue();

    $daily[$day]['min'] = min($daily[$day]['min'] ?? PHP_FLOAT_MAX, $temp);
    $daily[$day]['max'] = max($daily[$day]['max'] ?? PHP_FLOAT_MIN, $temp);
}

Cache aggressively and per-unit. The package performs no caching in 2.x. Cache current weather for 5–10 minutes and forecasts for 20–30 minutes, keyed by (endpoint, location, units, lang). A PSR-16 cache works well; store either the parsed objects (they serialize cleanly) or the raw array from getRawWeather()->getRawData().

Use raw responses for fields the package does not model. getRawWeather() exposes the decoded JSON, which is the escape hatch for visibility, rain/snow volumes, timezone offsets, and any new API fields. Prefer raw access over forking the package for one missing property.

Mock the HTTP layer in tests. The constructor accepts a PSR-18 client and PSR-17 request factory; inject a stub returning fixture JSON. This keeps unit tests fast and deterministic, and lets you exercise 401/404/429 paths without hitting OWM.

Handle errors as a first-class branch. Catch Cmfcmf\OpenWeatherMap\Exception, distinguish client errors (bad key, unknown location) from transient ones (429, 5xx), and fall back to stale cache where possible. Do not let a weather widget take down a page.

Pass units and language explicitly on every call. Defaults exist, but making them explicit documents intent and prevents a mix of Kelvin, Celsius, and Fahrenheit in logs and caches. Keep the language code tied to your UI locale, not to a hard-coded 'en'.

Gotchas and Tips

  • Key activation is delayed. A freshly created OWM key often returns 401 for minutes to a couple of hours. Do not chase this as a code bug.
  • The third argument is language, not units. Signature order is location, units, language. Passing 'de' as units produces a confusing error or wrong unit.
  • temperature->min/max on current weather are observation min/max, not the day's forecast range. Do not label them as daily highs and lows.
  • Nullable structure. precipitation, wind->direction, sun->rise/set (polar day/night), and rain/snow blocks may be absent or null. Guard before dereferencing.
  • All timestamps are UTC. lastUpdate, forecast time, and sunrise/sunset are UTC DateTime objects. Convert at the presentation layer, not in the domain object.
  • Coordinates is (latitude, longitude). Reversing them silently returns weather for the wrong hemisphere.
  • PSR-18 discovery needs a client and a Composer plugin allowance. On Composer 2.2+, php-http/discovery must be allowed in config.allow-plugins. If no client is installed, discovery throws at construction time — install Guzzle or Symfony HttpClient.
  • The API key is a query parameter. It appears in URLs, so scrub it from access logs, HTTP client debug logs, and error trackers. Prefer injecting a client with logging disabled for these calls.
  • Plan limits bite quickly. History requires a paid subscription; UV and air-pollution endpoints depend on the current plan. Free-tier rate limits are low, so batch loops over many cities need throttling and 429 backoff.
  • Forecast length is an API contract, not a package guarantee. Slice to the number of days you display; do not assume exactly 40 entries forever.
  • Icons are codes, not URLs. $weather->weather->icon returns values like 01d; map them to your own asset URLs so you control branding and CDN behavior.
  • Version pinning matters. The 1.x → 2.x upgrade changed the constructor (PSR-18/PSR-17) and requires PHP 8.1+. Pin a major version and read the changelog before upgrading.
  • Extension point is composition, not inheritance. Wrapping OpenWeatherMap in your own service is cleaner than subclassing it; for endpoints not yet supported, call the OWM HTTP API directly with the same PSR-18 client.
  • Debugging tip: when a parsed property looks wrong, call the raw method for the same request and compare. If the raw JSON has the field, the parser is the issue; if not, it is a plan, location, or parameter problem.
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.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums