Php-tekenreeks ontsnapt. Vraag: Alle aanhalingstekens in een string vervangen door ontsnapte aanhalingstekens? php dubbele en enkele aanhalingstekens

2007.11.08 16:07

Ik ondervond een probleem met het automatisch toevoegen van aanhalingstekens in PHP bij het invoeren van informatie in de database.

Na wat speurwerk op internet ontdekte ik dat het probleem kan worden opgelost door de serverinstellingen te wijzigen met behulp van de richtlijnen in .htaccess: magic_quotes_gpc en magic_quotes_runtime.

Ze zeggen (en ik geloof het zelfs) dat de ontwikkelaars van de PHP-taal, omdat ze niet in staat waren het grootste deel van de PHP-programmeurs te dwingen code van hoge kwaliteit te schrijven, besloten om voor de veiligheid van ons DBMS te zorgen en de automatische toevoeging van schuine strepen te introduceren vóór speciale tekens. Slashes worden toegevoegd op basis van php.ini-richtlijnen (magic_quotes_gpc en magic_quotes_runtime).

Richtlijnen worden gezamenlijk ‘magische citaten’ genoemd, maar ik noem ze ‘helquotes’. In een goed geschreven applicatie is er immers geen noodzaak voor automatische offertes, bovendien zitten extra offertes in de weg en moeten ze verwijderd worden.

De eerste richtlijn - magic_quotes_gpc - betekent dat PHP automatisch schuine strepen toevoegt aan gegevens die van de gebruiker afkomstig zijn - van POST-, GET-verzoeken en cookies. De tweede variabele - magic_quotes_runtime - betekent dat er schuine strepen worden toegevoegd aan gegevens die worden ontvangen tijdens de uitvoering van het script, bijvoorbeeld uit een bestand of database. Sommige functies die dergelijke informatie presenteren, gebruiken dus aanhalingstekens.

Als je zo’n opdringerige service wilt weigeren, schakel je (in die zeldzame en gelukkige situatie waarin je de volledige eigenaar van de server bent) deze configuratievariabelen uit in het php.ini-bestand, of (tenzij je natuurlijk het hosten van de site op gratis hosting) kunt u wijzigingen aanbrengen in het .htaccess-bestand. Dit is een bestand dat lokale - voor één map, en niet voor de hele server - apache-instellingen bevat. En voeg er de volgende regels aan toe.

Dit korte artikel laat zien hoe en waar je quotes in PHP kunt gebruiken.

Enkele aanhalingstekens (apostrofs) in PHP

Tekenreeksen tussen enkele aanhalingstekens worden op geen enkele manier door PHP verwerkt. Dat wil zeggen dat enkele aanhalingstekens de tekst tussen deze aanhalingstekens weergeven zoals deze is.

// Correcte echo "Hoe gaat het met het leven?"; echo "Hoe gaat het met het leven? $name"; echo "Hoe is het leven?".$name; // Onjuiste echo "Hoe gaat het? $name";

Speciale tekens tussen enkele en dubbele aanhalingstekens

Om ervoor te zorgen dat bijvoorbeeld het tabteken (\t) wordt geïnterpreteerd als een tabteken in plaats van als een schuine streep en de letter t, moet u de tekstregel die het tabteken bevat tussen dubbele aanhalingstekens plaatsen. Je kunt \' en \\ alleen tussen enkele aanhalingstekens gebruiken. Alle andere escape-reeksen (\n, \r, \$, etc.) zijn niet toegestaan ​​tussen enkele aanhalingstekens.

// Onjuiste echo "Hoe gaat het?\n"; // Correcte echo "Hoe gaat het?\n";

Om dubbele aanhalingstekens binnen een tekenreeks te voorkomen, plaatst u de aanhalingstekens vóór de backslash \" .

// Onjuiste echo "Hoe gaat het met het leven?"; // Correcte echo "Hoe gaat het met het leven?"; echo "Hoe is het leven?";

Dubbele aanhalingstekens in PHP

Tekst tussen dubbele aanhalingstekens wordt heel anders behandeld. Variabelen tussen dubbele aanhalingstekens worden bijvoorbeeld vervangen door hun waarden. Dit maakt het handig om SQL-query's te schrijven met dubbele aanhalingstekens.

$query = "INSERT INTO tabel (bericht, auteur, tekst, datum) VALUES ("$id", "$author", "$text", "$date"");

Tekenreeksen in PHP worden omgeven door enkele of dubbele aanhalingstekens. Het belangrijkste verschil is dat je een variabele tussen dubbele aanhalingstekens kunt plaatsen:

Nu kunnen we een andere oplossing voor het probleem bedenken uit de les Variabelen in PHP:

Hoe vindt PHP een variabele in een string?

Het is eenvoudig. Weet jij nog welke tekens je in een variabelenaam kunt gebruiken? Dit zijn cijfers, letters en onderstrepingstekens _.

PHP neemt dus als naam alles wat tussen het $-symbool en het eerste verboden teken staat.

In de volgende code zal PHP de naam van de variabele verkeerd bepalen en een foutmelding genereren:

Resultaat in browser:

Opmerking: Ongedefinieerde variabele: pricerub in D:\OpenServer\domains\site\index.php op regel 3

Om PHP de naam van een variabele in een string correct te laten bepalen, moet je deze tussen accolades () plaatsen:

Resultaat in browser:

1499 wrijven.

Er bestaat geen duidelijke consensus over welke aanhalingstekens moeten worden gebruikt voor gewone tekenreeksen waarin niets hoeft te worden vervangen. Veel programmeurs gebruiken echter liever enkele aanhalingstekens.

Feit is dat dubbele aanhalingstekens bij veel mensen de associatie oproepen ‘er moet iets in deze regel worden ingevoegd’. Daarom raad ik aan om enkele aanhalingstekens te gebruiken voor gewone tekst, en alleen dubbele aanhalingstekens als u een variabele in de tekst moet vervangen. Voorbeeld:

Ontsnappen aan citaten

Als je aanhalingstekens in een string moet plaatsen, zijn er twee manieren om dit te doen:

In het tweede voorbeeld ontsnapt de backslash \ aan het volgende citaat, zodat PHP het als een string behandelt.

Wat moet er volgens jou gebeuren om alleen backslashes op het scherm weer te geven? Het zal immers aan het slotcitaat ontsnappen. Het is grappig, maar je moet een tweede schuine streep schrijven om aan de eerste te ontsnappen:


Als uw gebruikers goed en aardig zijn, zullen ze citaten van oude filosofen plaatsen, en de berichten zullen er ongeveer zo uitzien:

Geplaatst door Plato op 2 januari, 15:31

Er wordt gezegd dat ik heb gezegd: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.'


Als gebruikers slim zijn, zullen ze waarschijnlijk over wiskunde praten, en de berichten zullen als volgt zijn:

Geplaatst door Pascal op 23 november, 04:12

Basiswiskunde vertelt ons dat als x< n and y >n, x kan niet groter zijn dan y.


Hmm... Deze ontheiligers van onze beugels weer. Nou ja, vanuit technisch oogpunt zijn ze misschien dubbelzinnig, maar de browser zal ons dat vergeven, toch?


Oké, STOP, wat in vredesnaam? Een grappenmaker heeft javascript-tags op je forum geïntroduceerd? Iedereen die dit bericht op uw site bekijkt, downloadt en voert nu scripts uit in de context van uw site die kunnen doen wie weet wat. En dit is niet goed.

Niet letterlijk te nemen In de bovenstaande gevallen willen we onze database of browser op de een of andere manier vertellen dat dit alleen maar tekst is, doe er niets mee! Met andere woorden, we willen de speciale betekenissen van alle speciale tekens en trefwoorden "verwijderen" uit alle informatie die door de gebruiker wordt verstrekt, omdat we hem niet vertrouwen. Wat te doen?

Wat? Wat zeg je, jongen? Oh, je zegt, "afscherming"? En je hebt helemaal gelijk, neem een ​​koekje!
Als we escapen toepassen op de gebruikersgegevens voordat we deze samenvoegen met de query, is het probleem opgelost. Voor onze databasequery's zal het ongeveer zo zijn:
$naam = $_POST["naam"]; $naam = mysql_real_escape_string($naam); $query = "SELECTEER telefoonnummer VAN gebruikers WHERE naam = "$naam""; $resultaat = mysql_query($query);
Slechts één regel code, maar nu kan niemand onze database meer "hacken". Laten we nog eens kijken hoe de SQL-query's eruit zullen zien, afhankelijk van de gebruikersinvoer:
Alex
SELECTEER telefoonnummer VAN gebruikers WAAR naam = "Alex"
Mc Donalds
SELECTEER telefoonnummer VAN gebruikers WAAR naam = "Mc\"Donalds"
Joe"; DROP TABLE-gebruikers; --
SELECTEER telefoonnummer VAN gebruikers WAAR naam = "Joe\"; DROP TABLE-gebruikers; --"
mysql_real_escape_string plaatst zonder onderscheid een schuine streep voor alles wat een speciale betekenis kan hebben.


We passen de functie htmlspecialchars toe op alle gebruikersgegevens voordat deze worden uitgevoerd. Nu ziet de boodschap van de plaag er als volgt uit:

Geplaatst door JackTR op 18 juli, 12:56


Houd er rekening mee dat de waarden die van gebruikers worden ontvangen, niet daadwerkelijk "beschadigd" zijn. Elke browser parseert dit als HTML en geeft alles in de juiste vorm op het scherm weer.

Dat brengt ons terug bij... Al het bovenstaande demonstreert een probleem dat veel voorkomt bij veel systemen: tekst in tekst moet worden geëscaped als het niet de bedoeling is dat deze speciale tekens bevat. Bij het plaatsen van tekstwaarden in SQL moeten deze worden geëscaped volgens de SQL-regels. Bij het plaatsen van tekstwaarden in HTML moeten deze worden geëscaped volgens HTML-regels. Bij het plaatsen van tekstwaarden in (technologienaam) moeten deze worden geëscaped volgens de (technologienaam) regels. Dat is alles. Voor de volledigheid: er zijn natuurlijk andere manieren om met gebruikersinvoer om te gaan die wel of geen speciale tekens bevatten:
  • Geldigmaking
    U kunt controleren of de gebruikersinvoer overeenkomt met een bepaalde specificatie. Als u wilt dat een nummer wordt ingevoerd en de gebruiker voert iets anders in, moet het programma de gebruiker hiervan op de hoogte stellen en de invoer annuleren. Als dit allemaal correct is georganiseerd, bestaat er geen risico dat "DROP TABLE-gebruikers" worden betrapt op de plek waar de gebruiker "42" moest invoeren. Dit is niet erg praktisch om HTML/SQL-injecties te vermijden, omdat... Vaak moet u tekst in een vrije opmaak accepteren die trucjes kan bevatten. Validatie wordt doorgaans naast andere maatregelen gebruikt.
  • Sanering
    U kunt ook “stille” symbolen verwijderen die u als gevaarlijk beschouwt. Verwijder bijvoorbeeld eenvoudig alles dat op een HTML-tag lijkt, om te voorkomen dat het aan uw forum wordt toegevoegd. Het probleem is dat je volkomen legale delen van de tekst kunt verwijderen.
    Opgestelde SQL-statements
    Er zijn speciale functies die doen wat we wilden: de database de verschillen laten begrijpen tussen de SQL-query zelf en de informatie die door gebruikers wordt verstrekt. In PHP zien ze er ongeveer zo uit:
    $stmt = $pdo->prepare("SELECTEER telefoonnummer VAN gebruikers WAAR naam =?"); $stmt->execute($_POST["naam"]);
    In dit geval vindt het verzenden plaats in twee fasen, waarbij duidelijk onderscheid wordt gemaakt tussen het verzoek en de variabelen. De database heeft de mogelijkheid om eerst de structuur van het verzoek te begrijpen en deze vervolgens met waarden te vullen.

  • In de echte wereld worden deze allemaal samen gebruikt voor verschillende beschermingsniveaus. U moet altijd gebruik maken van validatie om er zeker van te zijn dat de gebruiker de juiste gegevens invoert. Vervolgens kunt u (maar bent u niet verplicht) de ingevoerde gegevens scannen. Als een gebruiker u duidelijk een script probeert te verkopen, kunt u het eenvoudigweg verwijderen. Vervolgens moet u gebruikersgegevens altijd escapen voordat u deze in een SQL-query plaatst (hetzelfde geldt voor HTML).