# Ievades validēšana un filtrēšana PHP ar filter_var

> Ievades validēšana PHP ar filter_var un filter_input_array: skaitļi, e-pasts, URL, Bool, atļauju saraksti un robežas. Ar koda piemēriem.

Avots: https://phpsos.de/lv/blog/eingaben-validieren-php/  
Aktuāls uz: 25.10.2026  
Pakalpojuma sniedzējs: PHP SOS, PHP ārkārtas palīdzība un serveru drošība. Tūlītēja palīdzība pa WhatsApp: https://wa.me/491736494914?text=Sveiki%2C%20PHP%20SOS%2C%20mums%20nepiecie%C5%A1ama%20pal%C4%ABdz%C4%ABba%20ar%20m%C5%ABsu%20PHP%20serveri.%20Uz%C5%86%C4%93mums%3A%20%E2%80%A6%20Vietne%3A%20%E2%80%A6

**Īsi sakot:** Ievadi PHP validējat ar `filter_var()` vai `filter_input_array()` un skaidriem noteikumiem katram laukam: tips, diapazons, garums un atļautās vērtības. Kas neder, tiek noraidīts, nevis kluso pārveidots. Validēšana ir svarīga tīriem datiem un mazākai uzbrukuma virsmai, taču neaizstāj ne Prepared Statements pret SQL injekciju, ne kontekstam atbilstošu kodēšanu pret XSS.

## Kāpēc „filtrēt visu" nav koncepcija

Daudzos vecākos PHP projektos katra faila sākumā ir cikls, kas visas `$_GET` un `$_POST` vērtības laiž cauri tīrīšanas funkcijai. Tas liekas drošs. Praksē tas reizēm noņem pārāk daudz, piemēram, apostrofus uzvārdos, un reizēm pārāk maz, jo viena un tā pati funkcija vienlaikus paredzēta SQL, HTML un failu nosaukumiem.

Jēdzīga validēšana strādā citādi: tā katram laukam jautā, kas tur atļauts. Pasūtījuma daudzums ir vesels skaitlis starp 1 un augšējo robežu. Šķirošanas lauks ir viena no trim fiksētām vērtībām. Datums ir noteiktā formātā un pēc cita datuma. Viss pārējais tiek noraidīts.

OWASP šeit izšķir divus līmeņus: **sintaktisko** pārbaudi, vai vērtībai ir pareizā forma, un **semantisko** pārbaudi, vai tā kontekstā ir jēdzīga. Abām jānotiek serverī; pārbaudes pārlūkā kalpo tikai ērtībai.

## Kādus filtrus PHP piedāvā

Filtru paplašinājums PHP ir iekļauts pēc noklusējuma. Svarīgākie validēšanas filtri saskaņā ar PHP rokasgrāmatu:

| Filtrs | Pārbauda | Svarīgas opcijas un norādes |
|---|---|---|
| `FILTER_VALIDATE_INT` | veselu skaitli | `min_range`, `max_range` |
| `FILTER_VALIDATE_FLOAT` | daļskaitli | `decimal` atdalītājam |
| `FILTER_VALIDATE_BOOL` | patiesuma vērtību | ar `FILTER_NULL_ON_FAILURE` atšķirams no „nepatiess" |
| `FILTER_VALIDATE_EMAIL` | e-pasta adreses formu | nepierāda, ka pastkaste pastāv |
| `FILTER_VALIDATE_URL` | URL formu | shēmu pārbaudīt pašiem, nav internacionalizētu domēnu |
| `FILTER_VALIDATE_IP` | IP adresi | karogi privātiem un rezervētiem diapazoniem |
| `FILTER_VALIDATE_REGEXP` | savu paraugu | paraugu noenkurot ar `^` un `$` |

Tīrīšanas filtrs `FILTER_SANITIZE_STRING` kopš PHP 8.1 ir novecojis. Kas to vēl lieto, tam validēšana jāpārceļ uz piemērotiem filtriem un izvadei jālieto `htmlspecialchars()`.

## filter_var PHP: veidlapas tīra pārbaude

Ar `filter_input_array()` visu veidlapu var pārbaudīt vienā solī pret definīciju. Nezināmi lauki pie tam netiek pārņemti:

```php
<?php
declare(strict_types=1);

$regeln = [
    'menge'   => ['filter' => FILTER_VALIDATE_INT,
                  'options' => ['min_range' => 1, 'max_range' => 50]],
    'email'   => FILTER_VALIDATE_EMAIL,
    'agb'     => ['filter' => FILTER_VALIDATE_BOOL, 'flags' => FILTER_NULL_ON_FAILURE],
    'versand' => ['filter' => FILTER_VALIDATE_REGEXP,
                  'options' => ['regexp' => '/^(standard|express)$/']],
];

$daten  = filter_input_array(INPUT_POST, $regeln) ?? [];
$fehler = [];

foreach ($regeln as $feld => $_) {
    if (!array_key_exists($feld, $daten) || $daten[$feld] === false || $daten[$feld] === null) {
        $fehler[] = $feld;
    }
}

if ($fehler !== []) {
    http_response_code(422);
    // Izvadīt kļūdas ziņojumu katram laukam, ievadi neapstrādāt
}
```

Ņemiet vērā stingros salīdzinājumus ar `===`: derīgu vērtību `0` vai tukšu virkni nedrīkst sajaukt ar neveiksmi. Kāpēc brīvi salīdzinājumi te ir bīstami, skaidro [Type Juggling: brīvie salīdzinājumi kā drošības risks](https://phpsos.de/lv/blog/type-juggling-php/). Kā PHP vispār nodrošina pieprasījuma datus, apraksta [Superglobals: $_GET, $_POST, $_FILES un citi](https://phpsos.de/lv/php/superglobals/).

## Kļūmes ar e-pastu, URL un brīvu tekstu

Daži filtri dara mazāk, nekā to nosaukums liek domāt:

1. **URL:** `FILTER_VALIDATE_URL` pieņem arī citas shēmas, ne tikai http un https. Pēc tam pārbaudiet shēmu ar `parse_url()` pret fiksētu sarakstu. Ja URL serveris atver pats, spēkā papildu noteikumi, skatiet [Server-Side Request Forgery novēršana PHP](https://phpsos.de/lv/blog/ssrf-in-php/).
2. **E-pasta adreses:** filtrs pārbauda formu, nevis piederību. Kam jābūt drošam, tas sūta apstiprinājuma saiti.
3. **Brīvs teksts:** vārdus, ziņas un adreses ar rakstzīmēm gandrīz nav jēgas ierobežot. Pārbaudiet garumu un rakstzīmju kodējumu, piemēram, ar `mb_check_encoding($wert, 'UTF-8')`, un izvadē paļaujieties uz kodēšanu.
4. **Regulārās izteiksmes:** bez `^` un `$` paraugs pārbauda tikai to, vai tas kaut kur parādās tekstā, nevis vai visa vērtība atbilst.
5. **Masīvi, nevis virknes:** uzbrucējs teksta vietā var nosūtīt masīvu. Bez tipa pārbaudes tas rada brīdinājumus vai negaidītu uzvedību.

> **Padoms:**
> Fiksētām izvēles vērtībām, piemēram, šķirošanai, valodai vai piegādes veidam, atļauju saraksts ar `in_array($wert, $erlaubt, true)` vai `match` izteiksme ir vienkāršāka un stingrāka nekā jebkura regulārā izteiksme.

Vēl viena bieža kļūda skar skaitļus ar nozīmi, piemēram, cenas, daudzumus vai atlaides. Tas, ka vērtība ir derīgs skaitlis, neko nesaka par to, vai tā kontekstā ir atļauta. Negatīvs daudzums, atlaide virs preču vērtības vai cena, kas pārņemta no veidlapas, nevis no datubāzes, ir klasiskas loģikas kļūdas. Cenas, atļaujas un statusu vērtības tāpēc vienmēr pieder serverim un nekad ne slēptiem veidlapas laukiem.

## JSON, webhook un imports: validēšana ārpus veidlapām

Daudzas ieejas šodien vairs nav veidlapas, bet JSON pieprasījumi no lietotnēm, maksājumu pakalpojumu webhook vai piegādātāju importa faili. Arī tur ir spēkā: vispirms droši ielasīt, tad pārbaudīt. OWASP iesaka ierobežot izmēru un ligzdošanas dziļumu, vēl pirms dati vispār tiek ielasīti. PHP daļu no tā veic `json_decode()` ar maksimālo dziļumu un `JSON_THROW_ON_ERROR`:

```php
<?php
$roh = file_get_contents('php://input', false, null, 0, 65536); // ne vairāk kā 64 KB
try {
    $daten = json_decode($roh, true, 16, JSON_THROW_ON_ERROR);
} catch (JsonException) {
    http_response_code(400);
    exit;
}
if (!is_array($daten) || !is_string($daten['bestellnummer'] ?? null)) {
    http_response_code(422);
    exit;
}
```

Webhook gadījumā pirms satura pārbaudes jāatbild uz jautājumu, vai ziņojums tiešām nāk no norādītā pakalpojuma. Ja pakalpojums piedāvā parakstu, pārbaudiet to un salīdziniet ar `hash_equals()`. Importa failiem katru rindu pārbaudiet kā veidlapu un kļūdu gadījumā tīri pārtrauciet, nevis pārņemiet pusdatus.

Kļūdu ziņojumiem jānosauc skartais lauks, bet noraidīto vērtību nedrīkst atdot atpakaļ nefiltrētu. Citādi pašā kļūdas ziņojumā rodas jauna izvades vieta, kas atkal jākodē.

## Ko validēšana nespēj nodrošināt

Validēšana samazina uzbrukuma virsmu, bet saskaņā ar OWASP nav galvenā aizsardzība pret injekciju. Uzvārds ar apostrofu ir derīgs un tomēr droši jānogādā datubāzē. Tas izdodas tikai ar Prepared Statements, kā rāda ceļvedis [SQL injekcijas novēršana PHP](https://phpsos.de/lv/ratgeber/sql-injection-php/). Un derīgs komentāra teksts kļūst nekaitīgs tikai ar kontekstam atbilstošu kodēšanu izvadē.

Pareizā secība tātad ir: saņemot validēt, apstrādājot parametrizēt, izvadot kodēt. Papildus pirms tam jāliek izmēru robežas: pieprasījumus, kas ir pārāk lieli, tīmekļa serverim un PHP vispār nevajadzētu pilnībā apstrādāt. Tam kalpo iestatījumi, piemēram, `post_max_size`, kas pēc PHP2Shell tāpat jāpārbauda.

## Kā PHP SOS palīdz konkrēti?

- Mēs apkopojam visas jūsu lietojumprogrammas ieejas: veidlapas, saskarnes, augšupielādes, importus un webhook.
- Mēs katram laukam nosakām, kas atļauts, un aizstājam vispārīgas tīrīšanas funkcijas ar skaidrām pārbaudēm.
- Mēs pārbaudām, vai datubāzes piekļuves un izvades ir nodrošinātas neatkarīgi no validēšanas.
- Mēs dokumentējam noteikumus tā, lai jūsu komanda tos var turpināt jaunām funkcijām.

Sistemātisku pārbaudi apraksta pakalpojums [drošības audits un penetrācijas tests](https://phpsos.de/lv/leistungen/sicherheitsaudit-penetrationstest/).


## Biežāk uzdotie jautājumi

**Kāda ir atšķirība starp validēšanu un tīrīšanu?**  
Validēšana pārbauda, vai vērtība atbilst gaidītajam, un pretējā gadījumā to noraida. Tīrīšana vērtību maina, piemēram, noņemot rakstzīmes. Drošības lēmumiem noraidīšana gandrīz vienmēr ir labāka, jo klusu mainīta vērtība var radīt jaunas kļūdas.

**Vai FILTER_SANITIZE_STRING vēl var lietot?**  
Filtrs kopš PHP 8.1 ir atzīmēts kā novecojis. PHP rokasgrāmata tā vietā iesaka izvadē lietot htmlspecialchars(). Esošais kods jāpāriet, jo novecojušās funkcijas nākamajās versijās var tikt izņemtas.

**Vai FILTER_VALIDATE_URL pietiek, lai saites padarītu drošas?**  
Nē. Filtrs pārbauda tikai adreses formu. Saskaņā ar rokasgrāmatu derīgam URL nav obligāti jāsākas ar http, tāpēc shēma pašiem jāpārbauda pret atļauju sarakstu, piemēram, https. Internacionalizētus domēnu vārdus filtrs noraida.

**Vai jāvalidē arī dati no savas datubāzes?**  
Izvadē tie tiek uzskatīti par neuzticamiem un attiecīgi kodēti. Atkārtota validēšana ir lietderīga, ja dati sākotnēji nākuši no ārpuses un tagad tiek izmantoti jaunā kontekstā, piemēram, kā faila nosaukums vai komandas daļa.

**Vai validēšana palīdz pret PHP2Shell?**  
Nē. PHP2Shell attiecas uz pieprasījumu apstrādi PHP interpretatorā, vēl pirms jūsu lietojumprogrammas kods vispār darbojas. Pret to palīdz tikai PHP atjauninājums ar visu PHP procesu pārstartēšanu.

## Avoti

- [PHP rokasgrāmata: filtru konstantes](https://www.php.net/manual/de/filter.constants.php)
- [OWASP Input Validation Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html)
- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
