Webbshop med PayPal

Ansvarsfriskrivning – Jag kan tyvärr inte garantera att den här artikeln resulterar i en felfri och säker applikation, och det är därför ditt ansvar att kontrollera din kod mot dokumentationen.

I den här artikeln ska vi skapa en – webbshop med PayPal och applikationen kommer att baseras på Classic API. Som du kanske såg i förra avsnittet av den här serien – Skapa Din Egen Nätbutik, så finns det tre steg i en transaktion på nätet:

  1. Kundvagn > ska samla in information om köpet, som kortnummer, adress, namn mm.
  2. Betalningsgateway > krypterar informationen och skickar den till säljarkonto
  3. Säljarkonto > processar informationen och sätter in pengarna på kontot

Vi kommer att använda oss av PayPal:s säljarkonto i den här artikeln.

 

Utvecklingsprocess

Utvecklingsprocessen för en applikation som använder PayPal:s API, har följande steg:

  1. Registrera dig som PayPal utvecklare.
  2. Integrera PayPal-funktionalitet till din webbplats och eventuella mobila applikationer.
  3. Testa dina PayPal transaktionsrutiner i PayPal:s Sandbox.
  4. Gå live med applikationen.
  5. Underhålla och uppgradera applikationen.

 

 

Skapa Utvecklar-konto

Så, till att börja med behöver du skapa ett utvecklar-konto hos PayPal, och du kan göra det här. Där behöver du sedan skapa autentiseringsuppgifter, vilket du kan se hur du ska göra här. Det finns två typer av autentiseringsuppgifter:

  • Signature API autentiseringsuppgifter
  • Certificate API autentiseringsuppgifter

Båda kan användas men PayPal rekommenderar Certificate av säkerhetsskäl. Båda varianterna innehåller tre autentiserings-värden:

  • API Användarnamn
  • API Lösenord
  • Certifikat

Det är dessa som skickas tillsammans med anrop till PayPal API.

Tänk på! Du måste ha ett PayPal Business-konto för att göra anrop till PayPal:s live servrar.

 

Olika Betalningsalternativ

PayPal har ett antal olika betalningsalternativ och det gäller att välja den som passar bäst för just din sida. Men detta kan vara minst sagt förvirrande, då det finns så många alternativ.

 

  • Express Checkout – Med den främsta PayPal tjänsten: Express Checkout kan du få betalningar utan att ha ett konto och utan att behöva fylla speciella kriterier förutom att verifiera ditt PayPal konto (antingen via ett bankkonto eller ett kreditkort). Tidigare kunde man endast ta Express Checkout betalningar från registrerade PayPal-användare, men PayPal har lagt till en kreditkorts alternativ för icke-PayPal-användare, vilket gör denna tjänst tillgänglig för praktiskt taget vem som helst som har ett av dom större kreditkorten (VISA, MasterCard, osv.)
    • Tänk på: Express Checkout processen sker på PayPals plattform och kan därför aldrig bli helt integrerade i din webbplats användargränssnitt.
  • Direct Checkout – Direktbetalnings metoden gör det möjligt att ta emot kreditkortsbetalningar direkt via ett API-anrop. Detta gör att du kan genomföra hela betalningsprocessen på din webbplats, vilket möjliggör en mer komplett shoppingupplevelse för kunderna.
  • Recurring Payments – Detta gör att du kan ställa in ett återkommande transaktion (dvs. en abonnemangs betalning).
  • Mass Payments – Denna metod gör att man kan föra över pengar till flera konton på samma gång.
  • Adaptive Payments – Här är ett annat API för att skicka pengar till flera mottagare, med vissa skillnader från Massbetalnings API:n.

Listan är inte helt komplett, men den innehåller dom populäraste alternativen (se dokumentationen för fler produkter).

 

 

Att Göra API Anrop

PayPal stödjer två huvudsakliga format över HTTP, nämligen: NVP och SOAP. NVP står för ”Name, Value Pair”, och SOAP står för ”Simple Object Access Protocol”. Jag kommer att använda mig av NVP, eftersom SOAP trots sitt namn har ett relativt komplex syntax.

Var och en a dessav API-metoder har olika parametrar, men de båda delar på vissa grundläggande parametrar, som används för att identifiera API kontot och underteckna transaktionen.

Dessa innefattar:

  • USER Din PayPal API användarnamn.
  • PWD Din PayPal API lösenord.
  • VERSION Versions nummer för NVP API service; 95.0 (som är den senaste vid skrivande stund).
  • SIGNATURE Din PayPal API signatur sträng. Denna parameter är valfri om man använder ett certifikat för autentisering.
  • Den sista parameter som krävs är METHOD, vilken deklarerar den API metod vi anropar.

 

Klass för anrop

Anrop görs över HTTPS. Vi använder cURL för att bygga förfrågan, och kapslar in hela processen i en klass:

<?php

class Paypal {
    /**
     * Sista error meddelande(n)
     * @var array
     */
    protected $_errors = array();

    /**
     * API autentiseringsuppgifter
     * Använd korrekt autentiseringsuppgifter (Live / Sandbox)
     * @var array
     */
    protected $_credentials = array(
        'USER' => 'seller_1227648999_cr8gr8designs.com',
        'PWD' => '1297608792',
        'SIGNATURE' => 'A3g66.FS11HYAf1mkHkkl3BDopE3kN.ddRE1wMrInvUEqO3UaLOvity47p',
    );

    /**
     * API endpoint
     * Live - https://api-3t.paypal.com/nvp
     * Sandbox - https://api-3t.sandbox.paypal.com/nvp
     * @var string
     */
    protected $_endPoint = 'https://api-3t.sandbox.paypal.com/nvp';

    /**
     * API Version * @var string */
    protected $_version = '74.0';

    /**
     * Skapar API förfrågan
     * @param string $method sträng för API metod som ska anropas
     * @param array $params Ytterligare anrops parametrar
     * @return array / boolean Svars array / boolean false vid misslyckande */
    public function request($method, $params = array()) {
        $this->_errors = array();
        if (empty($method)) { // Kolla så att API metod inte är tom
            $this->_errors = array('API metod fattas');
            return false;
        }
        // Våra anrops parametrar
        $requestParams = array(
            'METHOD' => $method,
            'VERSION' => $this->_version
                ) + $this->_credentials;
        // Bygg NVP sträng
        $request = http_build_query($requestParams + $params);

        //cURL inställningar
        $curlOptions = array(
            CURLOPT_URL => $this->_endPoint,
            CURLOPT_VERBOSE => 1,
            CURLOPT_SSL_VERIFYPEER => true,
            CURLOPT_SSL_VERIFYHOST => 2,
            CURLOPT_CAINFO => dirname(__FILE__) . '/cacert.pem',  //CA cert fil 
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_POST => 1,
            CURLOPT_POSTFIELDS => $request
        );
        $ch = curl_init();
        curl_setopt_array($ch, $curlOptions);
        // Skicka förfrågan - behåll API respons
        $response = curl_exec($ch);
        // Kolla efter cURL error
        if (curl_errno($ch)) {
            $this->_errors = curl_error($ch);
            curl_close($ch);
            return false;
            //Hantera fel
        } else {
            curl_close($ch);
            $responseArray = array();
            parse_str($response, $responseArray);
            // Break the NVP string to an array
            return $responseArray;
        }
    }
}

Svaret tillbaka kommer att vara i NVP-format, och vi formatera om den till en array innan vi returnerar den.

Parameter ACK innehåller status för förfrågan:

Success

..eller:

SuccessWithWarning

…när förfrågan lyckas, och:

Error

…eller:

Warning

… när förfrågan misslyckas.

En förfrågan kan misslyckas av många anledningar, och det finns många olika skäl för varje API-metod, och dessa beskrivs i detalj i manualen. Vi ska gå igenom sätt att hantera dem lite senare. Kom ihåg att parametervärdena är skiftlägeskänsliga (skiljer på stora och små bokstäver).

 

Express Checkout

En av de mest populära API är Express Checkout, som gör att du kan ta emot betalningar utan att öppna en Website Payments Pro-konto (som endast är tillgänglig för verifierada USA konton) eller hosta själva transaktionen själv (vilket kräver ytterligare säkerhet).

Express Checkout processen fungerar på följande sätt:

1. Vi förfrågar efter en checkout token från PayPal med hjälp av transaktionsuppgifter;
2. Om det lyckas, ska vi omdirigera användaren till PayPal Checkout tillsammans med den mottagna TOKEN.
3. Användaren slutför eller avbryter betalningen på PayPal-plattformen och omdirigeras Tillbaka till Vår hemsida;
4. Vi slutför transaktionen, antingen när användaren omdirigeras tillbaka eller via en Instant Payment Notification (IPN).

PayPal - Express Checkout process
PayPal – Express Checkout process

 

 

 

1. Begär Checkout Token

Vi initiera Express Checkout processen genom att skicka in orderuppgifter till PayPal API, och får då tillbaka en token sträng som identifierar ordern. Denna token ska användas i nästa steg när vi ska omdirigera användaren till PayPal.

Här följer de parametrar som krävs:

  • METHOD
    Detta är API metod som vi använder (dvs. SetExpressCheckout).
  • RETURNURL
    Den URL som användaren kommer att omdirigeras till efter att betalningen är klar.
  • CANCELURL
    Den URL som användaren kommer att omdirigeras till efter att ha avbrutit betalningsprocessen.
  • PAYMENTREQUEST_0_AMT
    Transaktionens totala beloppet. Detta måste ha två decimaler och decimaltecknet är en punkt, och den valfria tusentalsavgränsare måste vara ett kommatecken.
  • PAYMENTREQUEST_0_ITEMAMT
    Den totala kostnaden för objekten i ordning, exklusive frakt, skatter och andra kostnader. Om det inte finns några extra kostnader, så borde det vara samma värde som PAYMENTREQUEST_0_AMT.

Vi kan ange ytterligare parametrar att lägga till mer information om ordern, varav vissa har standardvärden:

  • PAYMENTREQUEST_0_CURRENCYCODE
    Betalnings valuta, en kod på tre bokstäver. Standard är USD, för Svenska kronor är det SEK och du hittar en lista över giltiga koder på sidan Currency Codes i dokumentationen.
  • PAYMENTREQUEST_0_SHIPPINGAMT
    De totala fraktkostnaden för denna order.
  • PAYMENTREQUEST_0_TAXAMT
    Det totala skattebeloppet för denna order. Detta krävs om per-post skatten specificeras (se nedan).
  • PAYMENTREQUEST_0_DESC
    Order beskrivning.

Vi kan även lägga till information om enskilda artiklar i ordern:

  • L_PAYMENTREQUEST_0_NAMEm
    Artikelns namn.
  • L_PAYMENTREQUEST_0_DESCm
    Artikelns beskrivning.
  • L_PAYMENTREQUEST_0_AMTm
    Artikelns kostnad.
  • L_PAYMENTREQUEST_0_QTYm
    Mängden av en artikel

Variableln m identifierar en enskild artikel. (Använd samma variabel för alla detaljer i samma artikel.)

Det finns många andra valfria parametrar, som finns i API-dokumentationen. Vi kommer att använda metoden request() som vi skrev i klassen Paypal, för att bygga anropet till SetExpressCheckout:

// Parametrar till Paypal->request()
$requestParams = array(
    /* URL användaren ska skickas tillbaka till efter slutförd betalning */
    'RETURNURL' => 'http://www.yourdomain.com/payment/success',
    /* URL användaren ska skickas tillbaka till om denne avbryter betalning */
    'CANCELURL' => 'http://www.yourdomain.com/payment/cancelled'
);
$orderParams = array(
    'PAYMENTREQUEST_0_AMT' => '500', 
    'PAYMENTREQUEST_0_SHIPPINGAMT' => '4', 
    'PAYMENTREQUEST_0_CURRENCYCODE' => 'GBP', 
    'PAYMENTREQUEST_0_ITEMAMT' => '496'
);
$item = array(
    'L_PAYMENTREQUEST_0_NAME0' => 'iPhone', 
    'L_PAYMENTREQUEST_0_DESC0' => 'White iPhone, 16GB', 
    'L_PAYMENTREQUEST_0_AMT0' => '496', 
    'L_PAYMENTREQUEST_0_QTY0' => '1'
);
$paypal = new Paypal();
$response = $paypal->request('SetExpressCheckout', $requestParams . $orderParams . $item);

 

2. Omdirigera till PayPal

Om anropet till metoden är framgångsrikt, kommer vi att få en Checkout token som finns i TOKEN parametern av respons-arrayn.

if (is_array($response) && $response['ACK'] == 'Success') {
    // Anrop lyckades 
    $token = $response['TOKEN'];
    // skicka tillbaka användaren
    header('Location: https://www.paypal.com/webscr?cmd=_express-checkout&token=' . urlencode($token));
}

Användaren går nu igenom köpprocessen på PayPals webbplats. När PayPal bekräftar eller avbryter transaktionen, kommer användaren att återvända till en av de webbadresser som vi har angett i förfrågan.

 

 

3. Slutför Transaktion

Förutsatt att användaren bekräftar transaktionen, kommer dom att omdirigeras till vår hemsida genom PayPal. Nu bör vi använda två API metoder: DoExpressCheckoutPayment som kommer att slutföra transaktionen, men innan dess, kanske vi vill kanske få ytterligare information om köparen med hjälp av GetExpressCheckoutDetails.

PayPal omdirigerar användaren tillbaka från köpet tillsammans med checkout token, som vi kommer att använda för att anropa dessa metoder. Denna token kommer att finnas tillgänglig i URL-query parametern via token parametern. Vi kommer att kontrollera för dess existens i bekräftelse URL och sedan skicka våra API anrop om vi hittar den.

GetExpressCheckoutDetails metod krävde endast checkout
token. DoExpressCheckoutPayment kräver ett par ytterligare parametrar:

  • PAYMENTREQUEST_0_PAYMENTACTION
    Detta är åtgärden betalningen. Det ska vara inställd på Sale om vi inte har angett en annan åtgärd i SetExpressCheckout metoden (möjliga värden inkluderar Authorization och Capture).
  • PAYERID
    Detta är en unik identifikation för PayPal-konto. Även detta, returneras i URL-query parametrar (i PAYERID parameter) och kan även hämtas från detaljerna som returneras av GetExpressCheckoutDetails.
if (isset($_GET['token']) && !empty($_GET['token'])) { 
    // Token parameter finns
    // Hämta checkout detaljer, inklusive köparens information.
    // Vi kan spara den för framtida referens eller cross-checka med den data vi har 
    $paypal = new Paypal();
    $checkoutDetails = $paypal->request('GetExpressCheckoutDetails', array('TOKEN' => $_GET['token']));
    // Slutför checkout transaktion
    $requestParams = array(
        'TOKEN' => $_GET['token'],
        'PAYMENTACTION' => 'Sale',
        'PAYERID' => $_GET['PayerID'],
        'PAYMENTREQUEST_0_AMT' => '500', // Same amount as in the original request
        'PAYMENTREQUEST_0_CURRENCYCODE' => 'GBP' // Same currency as the originalrequest
    );
    $response = $paypal->request('DoExpressCheckoutPayment', $requestParams);
    if (is_array($response) && $response['ACK'] == 'Success') { 
        // Betalning lyckades
        // Vi hämtar transaktions-ID för intern bokföring
        $transactionId = $response['PAYMENTINFO_0_TRANSACTIONID'];
    }
}

 

 

Direkt betalning

Med Direct Payment API kan man ta emot betalningar direkt på sin webbplats/applikation, vilket ger fullständig kontroll över utcheckningsprocessen. PayPal tenderar att pusha på användare att registrera och använda ett PayPal-konto, vilket ju är förståeligt men det strider mot våra intressen, som ju är att göra betalningsprocessen som smärtfri och tydlig som möjligt för våra kunder. Av denna anledning är full kontroll över utcheckningen att föredra, och det ger oss också fler alternativ för att optimera försäljningen och genererar mer försäljning.

PayPal - Direct Payment
Processen för PayPals Direct Payment

Processen är lite enklare än Express Checkout, eftersom hela interaktionen sker på vår egen hemsida, och vi behöver endast utföra ett API-anrop för att bearbeta en normal betalning: DoDirectPayment.

Tips: Ett par fler API begäran krävs om man vill utföra en transaktion som faktureras i efterhand (till exempel när man skickar produkten eller bekräftar odrertillgänglighet). Dessa skulle vara Authorization & Capture API metoder, som jag inte kommer gå igenom i det här inlägget, men alternativet finns.

 

doDirectPayment

Direkt betalning kräver andra parametrar än Express Checkout. Medan parametrar för transaktionsdetaljer liknar varandra, kräver metoden även kreditkort och adressinformation.

doDirectPayment grundläggande parametrar:

  • METHOD
    Detta är DoDirectPayment.
  • IPADDRESS
    Detta är IP-adressen för kunden. I PHP, kan vi hämta det med hjälp av superglobaln $_SERVER[’REMOTE_ADDR’]. Du måste göra lite mer arbete för att få IP-adress när det handlar uppställningar som har en proxy mellan PHP processen och utanför nätet (t.ex. nginx).
  • PAYMENTACTION
    Detta är den typ av åtgärder som vi vill utföra. Ett värde på Sale indikerar en omedelbar transaktion. Värdet Authorization indikerar att denna transaktion inte kommer att utföras omedelbart, utan snarare kommer att fångas senare använder Authorization & Capture API nämnde tidigare.

Kreditkortsuppgifter:

  • CREDITCARDTYPE
    Kredit-korttyp (Visa, Mastercard, etc.). Se API-dokumentation för hela listan.
  • ACCT
    Den kreditkortsnummer. (Inte du älskar dessa förkortade nyckelnamn?) Detta måste överensstämma med den speciella formatet kortets typ.
  • EXPDATE
    Den utgångsdatum, i MMÅÅÅÅ format (dvs ett tvåsiffrigt månad och ett år fyrsiffrigt, som en sträng).
  • CVV2
    The ”kortverifieringsvärdet” eller säkerhetskod, som det ibland kallas.
  • Information om betalaren och adressparametrar:
  • FIRSTNAMELASTNAME
    Betalarens förnamn och efternamn, respektive (i separata fält). Du kan också ange en e-postadress i ett e-post parameter, men det är inget krav.
  • CITY, STATE, COUNTRYCODE, ZIP
    Stad, stat, landskod (kod på två bokstäver) och postnummer är delar av adressen som alla behövs.
  • STREET, STREET2
    Skapar två linjer för adressen (endast det första krävs).

Denna adress kommer att användas i address verification system (AVS). Du får en specifik felkod om en transaktion har misslyckats på grund av en adressverifierings misslyckande.

Betalningsinformation parametrarna är desamma som de för Express Checkout, men med lite olika namn (AMT, ITEMAMT, CURRENCYCODE, SHIPPINGAMT, TAXAMT och fallande) och utan PAYMENTREQUEST_0_ prefix. Se föregående avsnitt eller API-dokumentation för specifika detaljer om dem.

Likaså artikelinformation parametrar liknande dem i Express Checkout. Dessa inkluderar L_NAMEm, L_DESCm, L_AMTm och L_QTYm, vilket ger dig detaljerad kontroll över posten detaljer i ordning sammanfattningen. Den m heltal variabel används för att redovisa flera objekt (ersätt med 0, 1 och så vidare för numrerade poster i ordning). Se API-dokumentationen för en omfattande lista med artikelinformation.

 

Utföra Transaktion

Att sända en en query med vår funktion request() är mycket likt GetExpressCheckoutToken. Vi passerar alla parametrar in i queryn fungerar exakt som förut, fast med metod satt till DoDirectPayment.

$requestParams = array(
    'IPADDRESS' => $_SERVER['REMOTE_ADDR'], 
    'PAYMENTACTION' => 'Sale'
);
$creditCardDetails = array(
    'CREDITCARDTYPE' => 'MasterCard', 
    'ACCT' => '9229801207473993', 
    'EXPDATE' => '012021',  /* MMÅÅÅÅ */
    'CVV2' => '977'
);
$payerDetails = array(
    'FIRSTNAME' => 'Daniel', 
    'LASTNAME' => 'Karjanlahti', 
    'COUNTRYCODE' => 'SWE', 
    'STATE' => '',
    'CITY' => 'Södertälje', 
    'STREET' => 'Prästgårdsvägen 10.', 
    'ZIP' => '15161'
);
$orderParams = array(
    'AMT' => '500',  /* Den totala kostnaden för transaktionen till köparen. */
    'ITEMAMT' => '496',  /* Summan av kostnaden för alla Artiklar denna beställning. */
    'SHIPPINGAMT' => '4',  /* Totala fraktkostnader för denna beställning. */
    'CURRENCYCODE' => 'SEK'
);
$item = array(
    'L_NAME0' => 'iPhone',
    'L_DESC0' => 'White iPhone, 16GB', 
    'L_AMT0' => '496',
    'L_QTY0' => '1'
);
$paypal = new Paypal();
$response = $paypal->request(
        'DoDirectPayment', 
        $requestParams + 
        $creditCardDetails + 
        $payerDetails + 
        $orderParams + 
        $item
);
if (is_array($response) && $response['ACK'] == 'Success') { 
    // Betalning lyckades
    // Vi hämtar transaktions-ID för intern bokhållning
    $transactionId = $response['TRANSACTIONID'];
}

Det finns gott om parametrar, men dom är relativt enkla.

 

Felhantering

I en perfekt värld skulle detta avsnitt inte ens existerar. I verkligheten kommer du att hänvisa till det ganska mycket. PayPal kan misslyckas en transaktion för en mängd olika skäl, inte alla som kan du kontrollera.

Den $responsvariabel som vi återvänt från vår paypalApiRequest() funktionen kan innehålla ett annat värde än Success för ACK parameter. Detta värde kan vara:

  • Success
    Indikerar en lyckad operation.
  • SuccessWithWarning
    Indikerar en framgångsrik verksamhet och att meddelanden returneras i det svar som du bör undersöka.
  • Failure
    Indikerar en misslyckad operation, och att svaret innehåller en eller flera felmeddelanden som förklarar misslyckandet.
  • FailureWithWarning
    Indikerar en misslyckad operation, och att meddelanden returneras i det svar som du bör undersöka.
    Detta ger oss två framgångs status och två fel status. Den mock koden ovan tester för Success värdet bara, men vi kunde ändra det för att leta efter SuccessWithWarning också; och kom ihåg att vi måste ta reda på vad varningen är. Ett vanligt scenario är att en Direktbetalnings avgift har tagits med framgång, men kreditkortsföretaget svarar att transaktionen har misslyckats, oavsett orsak.

Fel från PayPal returneras i responsen som fyra parametrar:

  • L_ERRORCODE0
    En numerisk felkod, som kan refereras mot PayPal’s error kodlista (som är omfattande).
  • L_SHORTMESSAGE0
    En kort felmeddelande som beskriver problemet.
  • L_LONGMESSAGE0
    En längre felmeddelande som beskriver problemet.
  • L_SEVERITYCODE0
    Svårighetsgrad.

Noll-delen i dessa parametrar är ett ökande heltal för multipla felmeddelande (1, 2, etc.).

Här är några vanliga fel du kan stöta på:

  • 10002
    Autentisering eller tillstånd misslyckades. Detta tyder oftast ogiltiga API meriter eller referenser som inte matchar den typ av miljö du arbetar i (t.ex. en levande eller sandlåda miljö).
  • 81 ***
    Saknad parameter. Det finns en hel del av dessa, allt börjar med 81. Varje hänvisar till en specifik obligatorisk parameter som saknas i förfrågan.
  • 104 **
    Ogiltigt argument. Detta tyder på att en av de medföljande parametrar har ett ogiltigt värde. Varje argument har specifika fel, allt börjar med 104. En vanlig man är 10413, som innebär att den totala kostnaden för de varukorg poster matchar inte beställningens belopp (dvs. den totala mängden parametern, AMT, inte lika posterna totala plus sjöfart, hantering, skatter och andra avgifter).

 

Ta Hand om Felmeddelanden!

PayPal:s felmeddelanden varierar och kan innehålla privat information som du garanterat inte vill att dina användare att se (t.ex. en ogiltig försäljar-konfiguration). Om så är fallet, ska man inte visa dessa felmeddelanden direkt till användarna, även om vissa av dem kan vara användbara.

I de flesta fall skulle jag göra följande:

  1. Sätt upp en vit-lista rad fel som kan visas på ett säkert sätt (t.ex. en saknad kreditkortsnummer och utgångsdatum);
  2. Kontrollera svarskoden mot den arrayen;
  3. Om felmeddelandet inte är i den vita listan, visa ett generiskt felmeddelande, till exempel ”Ett fel inträffade under hanteringen av din betalning. Försök igen om några minuter, eller kontakta oss om detta är en återkommande fråga. ”

Om ett fel inte finns i den vita-listade arrayn, ska man logga det till en fil på servern och skicka ett mail till administratören, tillsammans med alla detaljer så att denne känner till misslyckade betalningar. Att loggar PayPal förfrågningar och svar är god praxis oavsett om dom innehåller felmeddelanden, så att man kan övervaka och felsöka betalnings misslyckanden.

 

Okej, det här borde få dig att komma igång med dom två populäraste PayPal alternativen Express Checkout och Direct Checkout. Till nästa gång, koda smart 😉

 

Ansvarsfriskrivning – Jag kan tyvärr inte garantera att den här artikeln resulterar i en felfri och säker applikation, och det är ditt ansvar att kontrollera din kod mot dokumentationen.

 

Huvudsaklig Källa

PHP filter_var och filter_input

Inspiration ur boken ”PHP Object Oriented Solutions” av David Powers

Det finns sju funktioner som används för att validering av inmatning, men endast fyra som faktiskt gör något filtrering eller validering. Du styr vad som accepteras eller förkastas genom att en rad PHP konstanter som argument till funktionen. Det finns 50 konstanter förknippade med filterfunktioner, vilket gör dem mycket mångsidig, men samtidigt komplexa.

 

 

Filter funktioner

  • filter_has_var() Kontrollerar om en variabel av en viss inmatnings typ existerar
  • filter_id () Returnerar ID-nummer för ett specifierat filter
  • filter_input () Ta inmatning utanför skriptet och filtrera den
  • filter_input_array () Ta flera inmatningskällor utanför skriptet och filtrerar dem
  • filter_list () Returnerar en array med alla filter som stöds
  • filter_var_array () Ta flera variabler och filtrera dem
  • filter_var () Ta en variabel och filtrera den

Tre funktioner – filter_has_var(), filter_input(), och filter_input_array() – är utformad för att fungera med superglobal arrayer, till exempel $_POST och $_GET. Men istället för att använda superglobal variabeln, måste man hänvisa till arrayen med motsvarande filterkonstant.

 

Konstanter » superglobal

Dessa filter funktioner är utformad för att fungera med superglobal arrayer, till exempel $_POST och $_GET. Men istället för att använda superglobal variabler, måste du hänvisa till den med motsvarande filterkonstant.

De konstanter och deras motsvarigheter listas här nedanför:

  • INPUT_COOKIE     $_COOKIE variabler
  • INPUT_ENV           $_ENV variabler
  • INPUT_GET            $_GET variabler
  • INPUT_POST         $_POST variabler
  • INPUT_REQUEST  $_REQUEST variabler
  • INPUT_SERVER     $_SERVER variabler
  • INPUT_SESSION   $_SESSION variable

 

filter_input och filter_var

Två av filter-funktionerna används för validering av enskilda variabler: filter_input() och filter_var(). Skillnaden mellan dem är att filter_input() hanterar en variabel som har kommit från ett av superglobal array, till exempel $_POST; filter_var() hanterar en variabel som har kommit från någon annan källa, som till exempel en databas eller en include-fil.

 

Filter argument

filter_input funktionen tar fyra argument, nämligen:

  • $source: Detta indikerar superglobal array som innehåller variabeln som du vill filtrera. Du måste använda en av de konstanter som anges i tabell 4-2, till exempel, INPUT_POST.
  • $variableName: Detta är namnet på variabeln som du vill filtrera.
  • $filter: Det här är filtret som du vill använda. Du måste ange en av filterkonstanter . Alternativt kan du använda filter_id () med namnet på filtret. Om det här argumentet utelämnas, använder PHP standardfiltret.
  • $alternativ: Detta är en valfri array som innehåller eventuella tillval eller flaggor som du vill använda.

filter_var() tar inte den första av dessa argument ($source), men de övriga tre är desamma som för både filter_input(). och filter_var().
Eftersom båda funktionerna är väldigt lika varandra ska jag gå igenom båda under den här guiden, men låt oss börja med att experimentera med filter_var() genom att hårdkoda in vissa värden.

 

2 flaggor för alla filter

  • Flagga FILTER_REQUIRE_ARRAY

Detta avvisar alla värden som inte är en array. När denna flagga är satt innebär att filtret tillämpas på samtliga delar av arrayen. Det fungerar även på flerdimensionella arrayer, tillämpar filtret rekursivt till varje nivå.

  • Flagga FILTER_REQUIRE_SCALAR

Detta avvisar varje värde som inte skalär. Med andra ord måste värdet vara en av följande datatyper: Boolean, heltal, flyttal, resurs (till exempel en databas länk eller fil handtag), eller sträng.

 

Konstanter, Flaggor & Alternativ

Nu ska jag gå igenom konstanter, flaggor och alternativ som används av filter funktioner för validering av data.

Syntaxen ser ut så här:

filter_var(variabel, filter_konstant, alternativ)

 

Längst ner på sidan finns en textfält där du kan testa dom olika konstanterna med filter_var.

 

  • Filterkonstant FILTER_VALIDATE_BOOLEAN
  • Flagga FILTER_NULL_ON_FAILURE

När det används utan flagga, returnerar den true för ’1’, ’true’, ’on’, och ”yes”; annars returners FALSE. Om FILTER_NULL_ON_FAILURE flaggan är satt, returnerar falskt endast för ’0’, ’falsk’, ’av’, ”nej”, och en tom sträng; Returneras NULL för alla icke-booleska värden.

Exempel:

// boolean koll med FILTER_VALIDATE_BOOLEAN
// När man använder filter_var utan en flagga, så returnerar den true bara för '1', 'true', 'on', och "yes"; annars false. 
// Om FILTER_NULL_ON_FAILURE flaggan är satt, returnerar den falskt bara för '0', 'false', 'off', "no", 
// och vid en tom sträng; Returnerar NULL för alla icke-booleska värden.
$var = FALSE;
// kolla om $var innehåller en boolean
$filtered = filter_var($var, FILTER_VALIDATE_BOOLEAN);
// ger svaret bool(false)
var_dump($filtered);

echo '<br />';

$var = 'true';
// kolla om $var innehåller en boolean
$filtered = filter_var($var, FILTER_VALIDATE_BOOLEAN);
// ger svaret bool(true) eftersom
// PHP är smart nog att tolka en sträng 
var_dump($filtered);

Resultatet:

bool(false) 
bool(true)

  • Filterkonstant FILTER_VALIDATE_EMAIL

Kollar att ett värde matchar med email formatet.

Exempel:

$var = 'mail@cr8gr8designs.com';
// kolla om $var innehåller en email
$filtered = filter_var($var, FILTER_VALIDATE_EMAIL);
var_dump($filtered);

Resultatet:

string(23) "mail@cr8gr8designs.com"

  • Filterkonstant FILTER_VALIDATE_FLOAT
  • Alternativ decimal
  • Flagga FILTER_FLAG_ALLOW_THOUSAND

Söker efter ett flyttal eller heltal; returnerar false för någon annan datatyp. Decimal alternativ tillåter användning av ett kommatecken som decimal. Inställning på flaggan accepterar siffror innehållande en tusentalsavgränsare (komma är standard, men punkt används när decimal är satt till ’,’). Funktionens returnerade värde alltid fråntagen tusentalsavgränsare, med en punkt som decimaltecken.

Exempel:

$var = 10.3;
// kolla om $var innehåller en float
$filtered = filter_var($var, FILTER_VALIDATE_FLOAT);
var_dump($filtered);

echo '<br />';

$var = '10.3';
// kolla om $var innehåller en float
$filtered = filter_var($var, FILTER_VALIDATE_FLOAT);
var_dump($filtered);

Resultatet:

float(10.3) 
float(10.3)

  • Filterkonstant FILTER_VALIDATE_INT
  • Alternativ min_range max_range
  • Flaggor FILTER_FLAG_ALLOW_OCTALFILTER_FLAG_ALLOW_HEX

Checks for an integer; returns false for any other data type. Specify the minimum and maximum acceptable values as an associative array using min_range and max_range (you can set just one or both together). Flags permit octal and hexadecimal numbers. Rejects numbers with a decimal point, even if the fraction is 0, for example, 10.0.

Exempel:

$var = 10;
// kolla om $var innehåller en integer
$filtered = filter_var($var, FILTER_VALIDATE_INT);
var_dump($filtered); // ger int(10)

echo '<br />';

$var = '10';
// kolla om $var innehåller en integer
$filtered = filter_var($var, FILTER_VALIDATE_INT);
// detta ger svaret int(10) då PHP tolkar en sträng som 
// bara innehåller siffror som en integer
var_dump($filtered);

Resultatet:

int(10) 
int(10)

  • Filterkonstant FILTER_VALIDATE_IP
  • Flaggor FILTER_FLAG_IPV4, FILTER_FLAG_IPV6, FILTER_FLAG_NO_PRIV_RANGE, FILTER_FLAG_NO_RES_RANGE

Kontrollerar att ett värde är en IP-adress. Flaggor låter dig ange endast IPv4 eller IPv6, eller inte från privata eller reserverade intervall.

Exempel:

$var = '192.168.1.1';
// kolla om $var innehåller en IP-adress
$filtered = filter_var($var, FILTER_VALIDATE_IP);
var_dump($filtered);

Resultatet:

string(11) "192.168.1.1"

  • Filterkonstant FILTER_VALIDATE_REGEXP
  • Alternativ regexp

Validerar ett värde mot en Perl- kompatibelt reguljärt uttryck. Hela värdet returneras, inte bara den del som matchar det reguljära uttrycket.


  • Filterkonstant FILTER_VALIDATE_URL
  • Flaggor FILTER_FLAG_SCHEME_REQUIRED, FILTER_FLAG_HOST_REQUIRED, FILTER_FLAG_PATH_REQUIRED, FILTER_FLAG_QUERY_REQUIRED

Kontrollerar att ett värde överensstämmer med formatet på en webbadress, eventuellt med nödvändiga komponenter som anges med flaggor.

Exempel:

$var = 'http://cr8gr8designs.com';
// kolla om $var innehåller en URL
$filtered = filter_var($var, FILTER_VALIDATE_URL);
var_dump($filtered); // ger string(24) "http://cr8gr8designs.com"

Resultatet:

string(24) "http://cr8gr8designs.com"

  • Filterkonstant FILTER_SANITIZE_STRING
  • Flaggor FILTER_FLAG_NO_ENCODE_QUOTES, FILTER_FLAG_STRIP_LOW, FILTER_FLAG_STRIP_HIGH, FILTER_FLAG_ENCODE_LOW, FILTER_FLAG_ENCODE_HIGH, FILTER_FLAG_ENCODE_AMP

Tar bort alla taggar, inklusive HTML, PHP och XML. Flaggorna ange alternativ för att ta bort eller avkoda specialtecken med en ASCIIvärde mindre än 32 (LOW) eller större än 127 (HIGH), lämna citationstecken okodade och avkoda et-tecken (&).

Exempel:

$var = "<this> <is> <a> </tag>utanför <script";
$filtered = filter_var($var, FILTER_SANITIZE_STRING);
var_dump($filtered);

Resultatet:

string(12) " utanför "

  • Filterkonstant FILTER_SANITIZE_STRIPPED

Detta är en alias av FILTER_SANITIZE_STRING som var precis innan den här.


  • Filterkonstant FILTER_SANITIZE_EMAIL

Tar bort alla tecken förutom bokstäver, nummer och dessa tecken:

! # $ % & ' * + - / = ? ^ _ ` { | } ~ @ . [ ]

Exempel på tecken som tas bort;

å Å ä Ä ö Ö fi ∂ é † √ ç ≈

Kod-exempel:

$var = 'lördag_när_hör_œ_åäö&@mäil.comåÅäÄöÖfi∂é†√ç≈';
$filtered = filter_var($var, FILTER_SANITIZE_EMAIL);
var_dump($filtered);

Resultatet:

string(22) "lrdag_nr_hr__&@mil.com"

  • Filterkonstant FILTER_SANITIZE_URL

Tar bort alla tecken förutom bokstäver, nummer och

$ - _ . + ! * ' ( ) , { } | \ ^ ~ [ ] ` < > # % " ; / ? : @ & =

Exempel:

$var = 'lördag_när_hör_œ_åäö&@mäil.comåÅäÄöÖfi∂é†√ç≈';
$filtered = filter_var($var, FILTER_SANITIZE_URL);
var_dump($filtered);

Resultatet:

string(22) "lrdag_nr_hr__&@mil.com"

  • Filterkonstant FILTER_SANITIZE_ENCODED
  • Flaggor FILTER_FLAG_STRIP_LOW, FILTER_FLAG_STRIP_HIGH, FILTER_FLAG_ENCODE_LOW, FILTER_FLAG_ENCODE_HIGH

URL-avkodar en sträng. Att ställa in flaggor tar valfritt bort eller kodar tecken med ASCII-värde på mindre än 32 (LOW) eller större än 127 (HIGH).

Exempel:

$var = 'lördag_när_hör_œ_åäö&@mäil.comåÅäÄöÖfi∂é†√ç≈';
$filtered = filter_var($var, FILTER_SANITIZE_ENCODED);
var_dump($filtered);

Resultatet:

string(176) "l%C3%B6rdag_n%C3%A4r_h%C3%B6r_%C5%93_%C3%A5%C3%A4%C3%B6%26%40m%C3%A4il.com%C3%A5%C3%85%C3%A4%C3%84%C3%B6%C3%96%EF%A3%BF%EF%AC%81%E2%88%82%C3%A9%E2%80%A0%E2%88%9A%C3%A7%E2%89%88"

  • Filterkonstant FILTER_SANITIZE_MAGIC_QUOTES

”Escapar” enkla och dubbla citationstecken, genom att sätta in ett bakstreck framför dem på samma sätt som de addslashes() funktion.


  • Filterkonstant FILTER_SANITIZE_NUMBER_FLOAT
  • Flaggor:
  1. FILTER_FLAG_ALLOW_FRACTION – Tillåter fraktions-avskiljare (som . )
  2. FILTER_FLAG_ALLOW_THOUSAND -Tillåter tusentals-avskiljare (som , )
  3. FILTER_FLAG_ALLOW_SCIENTIFIC -Tillåter vetenskaplig notation (som e och E)

Tar bort alla tecken utom siffror och plus och minustecken. Flaggorna valfritt tillåter en decimalbråk, tusentalsavgränsare, och vetenskaplig notation (med versaler eller gemener E). Decimalkommat och tusentalsavgränsare lämnas orörda. Om FILTER_FLAG_ALLOW_FRACTION inte är inställd, skall decimalkommat avlägsnas, men inte andelen, till exempel, 10,5 blir 105.

Exempel:

$var = '-hh12.44r__';
$filtered = filter_var($var, FILTER_SANITIZE_NUMBER_FLOAT);
var_dump($filtered);

Resultatet:

string(5) "-1244" // observera minus tecknet som följer med

Ett till exempel med flaggan FILTER_FLAG_ALLOW_FRACTION:

$var = '-hh12.4,4.02r__';
$filtered = filter_var($var, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
var_dump($filtered);

Resultatet:

string(9) "-12.44.02"

  • Filterkonstant FILTER_SANITIZE_NUMBER_INT

Tar bort alla tecken utom siffror och plus och minustecken. Den decimal avlägsnas, om den finns, men inte andelen, till exempel, 10,0 blir 100.

Exempel:

$var = '-hh12.4,4.02r__';
$filtered = filter_var($var, FILTER_SANITIZE_NUMBER_FLOAT);
var_dump($filtered);

Resultatet:

string(7) "-124402" // observera minus tecknet som följer med

  • Filterkonstant FILTER_SANITIZE_SPECIAL_CHARS
  • Flaggor FILTER_FLAG_STRIP_LOW, FILTER_FLAG_STRIP_HIGH, FILTER_FLAG_ENCODE_HIGH

Omvandlas till HTML-entiteter enkla och dubbla citationstecken, <,>, &, och tecken med en ASCIIvärde mindre än 32. När Ställa in flaggor valfritt avlägsnar tecken med ASCIIvärde mindre än 32 (LOW) eller större än 127 (HIGH ), eller kodar tecken med ASCII värde större än 127.

Exempel:

$var = '<div>Innehåll & källkod</div>';
$filtered = filter_var($var, FILTER_SANITIZE_SPECIAL_CHARS);
var_dump($filtered);

Resultatet:

string(51) "<div>Innehåll & källkod</div>"

Om du kollar på källkoden för sidan, så ser det ut så här:

string(36) "&lt;div&gt;Innehåll &amp; källkod&lt;/div&gt;"

  • Filterkonstant FILTER_CALLBACK
  • Alternativ användar-definierad funktion eller metod

Anropar en användar-definierad function för att filtrera data.


  • Filterkonstant  FILTER_UNSAFE_RAW
  • Flaggor FILTER_FLAG_STRIP_LOW, FILTER_FLAG_STRIP_HIGH, FILTER_FLAG_ENCODE_LOW, FILTER_FLAG_ENCODE_HIGH, FILTER_FLAG_ENCODE_AMP

Gör ingenting.

Flaggorna anger alternativ för att ta bort eller koda specialtecken med en ASCIIvärde mindre än 32 (LOW) eller större än 127 (HIGH) och koda et-tecken (&).

Exempel:

$var = '<div>Innehåll & källkod</div>';
$filtered = filter_var($var, FILTER_UNSAFE_RAW);
var_dump($filtered);

Resultatet:

string(31) "
Innehåll & källkod
"

..och om man kollar på källkoden ser man det här:

string(31) ""
<div>Innehåll & källkod</div>
""

FILTER_UNSAFE_RAW exempel med flaggan FILTER_FLAG_STRIP_HIGH

$var = '<div>Innehåll & källkod</div>';
$filtered = filter_var($var, FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_HIGH);
var_dump($filtered);

Resultatet:

string(27) "
Innehll & kllkod
"

FILTER_UNSAFE_RAW exempel med flaggan FILTER_FLAG_STRIP_LOW

$var = '<div>Innehåll & källkod</div>';
$filtered = filter_var($var, FILTER_UNSAFE_RAW, FILTER_FLAG_ENCODE_HIGH);
var_dump($filtered);

Resultatet:

string(51) "
Innehåll & källkod
"

Här nedanför kan du testa dom olika filterkonstanterna med filter_input() metoden. Koden kommer från boken ”PHP Object Oriented Solutions” av David Powers:


filter_id

Du kan även använda filter_id istället för konstanterna så här:

$var = 10;
$filtered = filter_var($var, filter_id('int'));
var_dump($filtered);

…och du får fram en lista över namn du kan använda med filter_list() metoden:

array(19) {
  [0]=> string(3) "int"
  [1]=> string(7) "boolean"
  [2]=> string(5) "float"
  [3]=> string(15) "validate_regexp"
  [4]=> string(12) "validate_url"
  [5]=> string(14) "validate_email"
  [6]=> string(11) "validate_ip"
  [7]=> string(6) "string"
  [8]=> string(8) "stripped"
  [9]=> string(7) "encoded"
  [10]=> string(13) "special_chars"
  [11]=> string(18) "full_special_chars"
  [12]=> string(10) "unsafe_raw"
  [13]=> string(5) "email"
  [14]=> string(3) "url"
  [15]=> string(10) "number_int"
  [16]=> string(12) "number_float"
  [17]=> string(12) "magic_quotes"
  [18]=> string(8) "callback"
}

Om vi tar en titt på filterkonstanten FILTER_SANITIZE_NUMBER_FLOAT med följande kod:

// där $_POST['number'] är lika med 1234.567
$filtered = filter_var(INPUT_POST, 'number', FILTER_SANITIZE_NUMBER_FLOAT);
var_dump($filtered);

Detta kommer att ge resultatet:

string(6) "123456"

Det här oväntade resultat får man eftersom sanerings filtret endast avlägsnar olagliga eller oönskade tecken. För att styra den mer exakt, måste man använda lämpliga flaggor och alternativ. Så, låt oss ta en titt på hur du lägger till flaggor och alternativ till ett filter.


Flaggor & alternativ

Det är här saker och ting börjar bli komplicerade. Formatet på den sista valfria argumentet till filter_input() och filter_var() beror på om vi vill använda flaggor, alternativ, eller både och. Dom tillgängliga alternativen och flaggorna har vi precis gått igenom. Syntaxen för att lägga till flaggor och alternativ ser likadan ut för både filter_input() och filter_var():

$var = 1234.56;
// filter_var($variabel, KONTANT, FLAGGA)
$filtered = filter_var($var, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);

Man kan lägga till flera flaggor åt gången, som då separeras med vertikalstreck|. Så för att tillåta tusentals-avskiljare på förra exemplet gör man så här:

$var = 1234.56;
// filter_var($variabel, KONSTANT, FLAGGA1 | FLAGGA2)
$filtered = filter_var($var, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION | FILTER_FLAG_ALLOW_THOUSAND);

Alternativ

Alternativ måste vara en flerdimensionell associativ array med nyckel värde par, där arrayn i den översta nivån har nyckeln ”option”. Så ta t.ex. FILTER_VALIDATE_INT som accepterar alternativen min_range och max_range. För att acceptera heltal bara mellan 10 och 100 (inklusive), lägger man till dessa alternativ:

$var = 17; $filtered = filter_var($var, FILTER_VALIDATE_INT, array('options' => array('min_range' => 10, 'max_range' => 100)));

Alternativen är alltså den här arrayn:

array('options' => array('min_range' => 10, 'max_range' => 100))

Både Flaggor & Alternativ

För att lägga till både flaggor och alternativ måste flaggorna in i den multidimensionella arrayn. Så för att tillåta tusentals-avskiljare på förra exemplet gör man på det här sättet:

$var = '1234.567';
$filtered = filter_var($var, FILTER_VALIDATE_FLOAT, array('options' => array('decimal' => ','), 'flags' => FILTER_FLAG_ALLOW_THOUSAND));

 

Att tänka på – Även om FILTER_VALIDATE_FLOAT accepterar siffror i europeisk stil med komma istället för punkt, när lämpligt alternativ och flagga är inställd, så blir värdet som returneras av filtret alltid med en punkt som decimal och den avlägsnar eventuella tusentalsavgränsare. Ett blanksteg accepteras inte som tusentalsavgränsare.


Flera variabler åt gången

För det mesta, behöver du filtreringen och valideringen att hantera flera variabler åt gången. För att undvika att behöva anropa filter_input() eller filter_var() funktionerna flera gånger finns motsvarande funktioner som kan bearbeta många variabler på samma gång: filter_input_array() och filter_var_array().

filter_input_array() tar följande argument:

  • $source: Detta indikerar vilken superglobal array som innehåller dom variabler man vill filtrera. M måste använda en av de konstanter som vi gick igenom i början.
  • $instructions: Detta är en valfri flerdimensionell array som anger hur variabler ska filtreras. Om det här argumentet utelämnas, används standardfiltret tillämpas (jag går igenom hur man ställer in standardfiltret lite senare i artikeln).

 

filter_var_array() tar följande argument:

  • $data: En array som innehåller de variabler man vill filtrera eller validera.
  • $instructions: Samma som för filter_input_array().

 

Sättet man skapar den flerdimensionella arrayn för det andra argumentet är mycket hur man ställer in flaggorna och alternativen för att filtrera enskilda variabler. På den översta nivån av arrayen bör det finnas ett element för var och en av de variabler som skall bearbetas. Det värde som tilldelas varje variabel ska antingen vara en filterkonstant eller en array som innehåller en kombination av följande: ”filter”, ”options” och ”flags”.

Här ser du exempel på alla varianter:

// kodexemplet kommer från boken "PHP Object Oriented Solutions" av David Powers
$data = array(
    'age'       => 39
    'rating'    => 5,
    'thousands' => '100,000.95',
    'european'  => '100.000,95');
);
$instructions = array(
    'name' => FILTER_SANITIZE_STRING,
    'price' => array('filter' => FILTER_VALIDATE_INT,
        'options' => array('min_range' => 1,
            'max_range' => 5)),
    'thousands' => array('filter' => FILTER_SANITIZE_NUMBER_FLOAT,
        'flags' => FILTER_FLAG_ALLOW_FRACTION |
        FILTER_FLAG_ALLOW_THOUSAND),
    'european' => array('filter' => FILTER_VALIDATE_FLOAT,
        'options' => array('decimal' => ','),
        'flags' => FILTER_FLAG_ALLOW_THOUSAND)
);
$filtered = filter_var_array($data, $instructions);

…och för att använda det här med filter_input_array() istället byter man bara ut den första parametern till en av superglobal konstanterna på det här sättet:

$filtered = filter_input_array(INPUT_POST, $instructions);

Som du ser blir detta väldigt krångligt och man råkar garanterat ut för en massa undantag (exeption). Nu kommer OOP till undsättning och man kan gömma den här komplexiteten bakom en klass.


Ställa in standard

Om du använder en typ av filter övervägande, kan du ange en standardfilter och även standardflaggor. Det finns tre ställen du kan göra detta: i php.ini; eller, om du använder en Apache-server, i Apaches konfigurationsfil httpd.conf, eller en .htaccess fil.

Konfigurations direktiv som behöver ändras är följande:
filter.default : Detta bör följas av en sträng med ett av namnen som genereras av filter_list() (se högre upp i artikeln).
filter.default_flags : Detta bör vara en av flaggkonstanterna. För att ställa in fler än en flagga, separera varje konstant med en enda vertikalstreck |. För att ställa in standardinställningarna i php.ini, tar man bort semikolonet från början av raden som innehåller den direktiv man vill använda, och lägger värdet efter likhetstecknet. Med följande direktiv ställer du in som standard att konvertera till HTML-entiteter, enkla och dubbla citattecken, större än, mindre än, och et-tecken &, medan standardflaggor bort alla tecken med ASCII värde på mindre än 32 eller större än 127:

filter.default = special_chars
filter.default_flags = FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH

För att ställa in värdena i httpd.conf eller en .htaccess fil, används php_value, följt av direktivet och dess värde som en mellanslags separerad lista såhär:

php_value filter.default special_chars
php_value filter.default_flags FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH

Okej, nu räcker det för den här gången. Vi fortsätter nästa gång med att bygga en valideringsklass. Tack för visat intresse och koda smart 😉

OOP PHP

Inspiration och fria översättningar från ”PHP Object Oriented Solutions” av David Powers.

I början av 60 talet började man inse att det var ohållbart att försöka uppdatera, felsöka och utveckla stora och komplexa applikationer med procedural/sekventiell kod som exekveras rad efter rad då detta var väldigt tidsödande och svårt.

Lösningen var att flytta funktionerna bort från huvudscriptet, och sedan klumpa ihop sammanhörande funktioner i logiska enheter som representerade en större och mer allmän ”kugghjul” i applikationen, dessa block kom att kallas för klasser och innehåller oftast metoder (funktioner i klasser kallas för metoder) och medlemsvariabler (även kallade egenskaper, attribut eller fält, i fortsättningen egenskaper) som används för att modifiera ett state av ett objekt (som är en instans av en klass).

Man skulle kunna göra jämförelsen med assemblerprogrammering och högnivåspråk, där den senare har en högre abstraktionsnivå och detsamma gäller med förhållandet mellan procedural kod och att arbeta med klasser och tillhörande metoder där en klass fungerar som en fabrik och varje metod är en avdelning som utför en specifik uppgift.

Så varför är det så bra med OOP sättet att programmera? Jo, genom att skapa så generiska moduler som möjligt får man fram script som är återanvändningsbar och så klart blir det mycket lättare att underhålla scripten.

Skydda dataintegritet » inkapsling

Inkapsling betyder att man ser till att varje enskild del av applikationen är avskilt från varandra och på det sättet inte kan störa (förutom genom angivna metoder). På detta sätt undviker man dominoeffekten som uppstår vid close coupling, så man bör eftersträva loose coupling. Man anger synlighet för egenskaper med tre olika nyckelord: public, private och protected, public är synlig från andra cript innanför och utanför klassen, protected och private o andra sidan är inte synliga utanför klassen och kan därför inte modifieras godtyckligt. Man kan även ange dessa nyckelord för metoders synlighet, på detta sätt och genom välplanerad struktur skyddar man viktiga egenskaper och funktioner i en applikation.

Exempel på public, private och protected egenskaper:

public $var1;
// både private och protected egensksnamn -
// föregås av dollartecken & understreck
private $_var2;
protected $_var3;

 

Polymorfism

Betyder egentligen bara att man får använda samma namn på liknande metoder och egenskaper (i kombination med inkapsling). För att illustrera polymorfismens funktionalitet kan vi ta ett exempel; ett människohuvud har en helt annan form än ett fågelhuvud, men dom har båda ungefär samma funktioner d.v.s. äta, andas, prata, se och så vidare, och därför är det vettigt att använda samma namn på båda. OOP PHP tillämpar detta till programmering genom att låta dig ge samma namn till metoder och egenskaper som spelar liknande roller i olika klasser.

Varje klass och objekt är oberoende, så dess metod- och egenskapsnamn är nära förknippade med klassen och alla objekt som skapats från den. Därför finns ingen risk för konflikter, så när en metod eller egenskap används på liknande sätt i olika klasser, är det vettigt att använda samma namn på dom.

Utöka klasser genom arv

När hjulet har uppfunnits, finns det ingen anledning att återuppfinna det – men man kan förbättra det, eller anpassa den för specialiserade användningsområden, så det finns ingen anledning att koda allt från grunden; man kan basera en ny klass på en befintlig.

Precis som du har ärvt vissa egenskaper från dina föräldrar, och utvecklat nya som tillhör dig, kan ett barn klass eller subklass i OOP ärva alla funktioner i sin moderklass (eller superklass), anpassa vissa av dem, och lägga till nya av sina egna.

Man kan utöka alla klasser, inbyggda, tredjepart eller egna men inte klasser som är deklarerade som final.

Underklassen ärver automatiskt alla egenskaper och metoder från sin superklassen, vilket kan vara en stor tidsbesparing om superklassen innehåller en hel del komplex kod. Du kan inte bara lägga till nya metoder och egenskaper, utan du kan också ”skriva över” befintliga metoder och egenskaper (detta är polymorfism i praktiken), anpassa dem till behoven hos den nya klassen.

Så hur ska man välja vad man utökar och vad man bygger från grunden? Jo, precis som det är tänkt med OOP så skapar man generiska klasser från grunden och utökar funktionaliteten för mer specifika klasser.

Loose Coupling

Loose coupling syftar ju som tidigare sagt till tekniken att skapa kod som inte är beroende av annan kod i applikationen genom att ange klara och individuella uppgifter till klasser och därmed inte kan störa andra delar av appen (förutom genom strikt angivna regler).

Loose coupling tekniken går ut på att så långt som mjöligt undvika utveckling för ett specifikt projekt, men det blir i slutändan oundvikligt att skriva metoder som riktar sig till specifika områden och kommer inte att kunna användas i andra applikationer. Tänk så här; när du skapar en klass, fråga dig själv om tekniken skulle kunna användas i andra projekt, om det kan så bör du göra klassen loose coupled d.v.s. så generisk som möjligt.

Design mönster

Många av dom problem som du ska lösa har andra utvecklare garanterat stött på tidigare. Om du hittar ett beprövat sätt att ta hand om ett problem så bör man ta efter lösningen.  Denna typ av kunskap har fått ett namn; design mönster. Ett design mönster är dock inte ett kodblock utan beskriver ett sätt att hantera ett problem.

Utvecklingen av OOP i PHP

Som sagt är PHP ingen OOP språk utan har OOP lösningar. Man började införa OOP i PHP version 3 men det fattades många essentiella funktioner där det största problemet var hur PHP hanterade variabler. Tyvärr fixades inte dom problemen under version 4 eftersom fokus låg på bakåtkompatibilitet.

Tillägget för OOP stöd var oväntad populär, men att fixa tidigarenämnda problemen skulle innebära att att existerande script skulle ”gå sönder”, men när PHP 5 släpptes Juli 2004 gjorde man detta ändå och det blev en radikal förändring av språket.

PHP: s hantering av föremål blev helt omskriven i PHP 5 för att förbättra prestanda och uppfylla kraven i standarder som är gemensamma för andra OOP språk. Den största förändringen från PHP 3 och 4 är det sätt objekt och deras egenskaper hanteras. Ta exemplet nedan:

$objectB = $objectA;

I PHP 3 och 4, skapar detta en kopia av $objectA och lagrar det som $objectB. Båda objekten agerar därefter oberoende av varandra; ändringar som gjorts i $objectA påverkar inte $objectB, och vice versa. Detta är känt som kopiering av värde och är sättet som PHP normalt hanterar variabler.

Men med PHP 5, istället för att göra en kopia av $objectA, lagras en referens till $objectA i $objectB. Båda variablerna refererar då till samma objekt; ändringar som görs i den ena påverka den andra. Detta är känt som kopiering genom referens. Sedan PHP 5, måste man, för att göra en kopia av ett föremål, använda nyckelordet clone:

$objectB = clone $objectA;

clone används endast med objekt (instanser av klasser), medan alla andra variabler fungerar på samma sätt som i PHP 4, det vill säga att man anger ett värde med tilldelnings operatorn för att skapa en kopia.

Andra viktiga skillnader i PHP5:

  • Synlighetsmodifierare som används för att styra åtkomst till egenskaper och metoder (Viktiga för inkapsling)
  • En enhetlig konstruktor namn,  __construct() istället för en metod med samma namn som klassen.
  • Stöd för explicit sanering av resurser genom en destructor funktion __destruct()
  • Stöd för gränssnitt (interface) och abstrakta klasser
  • final klasser
  • Statiska (static) egenskaper och metoder
  • Automatisk laddning av klasser

Utvecklingen av PHP 6 var under utveckling under en lång tid, och ursprungligen var det beräknat att komma ut i början av 2007, men som det ser ut nu kommer ingen version 6 över huvudtaget, utan man hoppar till 7 direkt (som man började jobba på 2014) mest p.g.a. att man vill slippa förvirringen kring gamla referenser till PHP 6, i böcker och artiklar.

Projektet PHP 6 övergavs officiellt Mars 2010 †

Artiklar om frågan PHP 6 / PHP 7;

 

 

Teckenkodning i PHP

Strängar som har tecken med accenter kan orsaka problem p.g.a. olika teckenkodningar, och detta i PHP speciellt.

Ta följande exempelkod som skriver ut En god dag, Världen!” i åtta olika språk:

<?php
echo '<div style="width:500px;margin:100px auto;text-aling:center;">';
echo '<h1>En god dag, Världen!<br />';
echo 'A good day, World!<br />';
echo 'Schönen Tag, Welt!<br />';
echo 'Une bonne journée, tout le monde!<br />';
echo 'يوم جيد، العالم<br />';
echo '좋은 일, 세계!<br />';
echo 'Một ngày tốt lành, thế giới!<br />';
echo 'こんにちは、世界!';
echo '</h1></div>';

 

Exempel på fel som uppstår vid teckenkodnings problem i PHP.
Figur 1-1 Exempel på fel som uppstår vid teckenkodnings problem.

Om man använder tecken med accenter kan detta skapa problem vid utskrift. Den allra vanligaste teckenkodningen på webben idag är UTF-8 som är satt som webbstandard av W3C, eftersom den har stöd för så gott som samtliga tecken. Om vi ändrar charset till UTF-8 med hjälp av en content-type header så försvinner problemet.

Lägg till följande kod precis efter start-taggen;

<?php
header('Content-Type: text/html; charset=utf-8');
Content-type header charset UTF-8
Figur 1-2 Efter att ha ändrat charset till UTF-8, med content-type header.

 

Om du skulle få problem med utskriften, kan du fixa det genom att lägga till en Content-type header i början av filen (eller ännu hellre i en initierigs-fil som sköter det nödvändiga inställningarna och laddningarna av resurser för att applikationen ska fungera som den ska), som då talar om vilken teckenkodning du vill använda.

En mycket bra artikel om teckenkodning, som jag tycker att du bör läsa;

Strängar är aningen speciella i PHP, och vill du läsa mer om Strängar hittar du allt om dom i dokumentationen, och då speciellt avsnittet ”Details of the String Type”;

…här är en liten, fritt översatt urdrag från den;

”Med tanke på att PHP inte har en specifik teckenkodning för strängar, kan man undra hur stränglitteraler är kodade…  [ ]  …Svaret är att strängar kodas på det sätt som dom kodades i skriptfilen. Således, om skriptet är skrivet i ISO-8859-1,  kommer strängen att kodas i ISO-8859-1 och så vidare.”

 

Gör skillnad på stora & små

Även om PHP inte ser någon skillnad på små och stora bokstäver i funktions- och klassnamn, ska du alltid tänka som att den gör det, eftersom det finns planer på att göra dem skiftlägeskänsliga på samma sätt som variabler.

Bygga klasser

Okej då var det dags att fortsätta med att bygga en klass. Vi börjar med en enkel exempel-klass som mest innehåller kommentarer som förklarar allt:

// dok_test.class.php
// här namnger jag filen med .class för att indikera
// att det handlar om en klass
class Dok_Test {
	// medlemsvariabel deklaration där variabelnamn -
	// föregås alltid av nyckelordet: public, protected eller private.
	// Om man anger ett startvärde får inte det vara beroende av kod
	// som kan förändras under exekvering, så värdet kan inte vara en metod.
	// private och protected börjas med understreck » $_namn
	// för att indikera att åtkomst är begränsad
	protected $_var;
	protected $_val;

	/**
	* metod deklaration
	* Använder $this nyckelordet för att referera till den här klassen
	*/
	public function displayProp() {
		// Man utelämnar $ i $_val då man använder $this
		// som pekar på den här klassen » Dok_Test
		echo $this->_val;
	}
}

Som du såg måste en medlemsvariabel föregås av ett synlighets nyckelord; public, protected eller private och om man använder protected eller private ska man ha understreck efter dollartecknet $_  följt av namnet, vilket hjälper utvecklaren att enkelt se vilken synlighet den har.

Så, vad ska man välja? Metoder fungerar ju som klassens reglage, och behöver därför oftast vara public, medan medlemsvariabler bör skyddas med protected eller private så att man inte kommer åt dom oavsiktligt. För att modifiera egenskaper använder man sig av getter och setter metoder.

Exempel på setter och getter metoder:

class Dok_Test {
    protected $_var;
    protected $_val;

    public function displayProp() {/* ..innehåll */}

	/**
	* För att kunna ändra på värdet av $val som är protected
	* måste man skapa en s.k. setter metod
	*/
	public function setValues($newVal, $newVar) {
		// sätt värde för protected $_val till $newVal
		$this->_val = $newVal;
		$this->_var = $newVar;
	}

	/**
	* Och för att kunna komma åt värdena för $val & $var
	* skapar man en getter metod
	*/
	public function getValues() {
		// return värdet på $val och $var som en array()
		return array($this->_val, $this->_var);
	}
}

För att använda en klass i ett script  måste man inkludera det, och likt funktioner kan klasser bara definieras en gång i ett script så det är vettigt att använda någon av; include_once och require_once metoderna för att bara ladda in den en gång i scriptet och undvika en ”Fatal error”.

För att använda en klass behöver man som sagt inkludera det, och sedan skapa en instans av den med hjälp av nyckelordet new;

// test.php
// inkludera klassen
include_once("dok_test.class.php");

// skapa en ny instans av Dok_Test
$obj = new Dok_Test();

// anropa metod från klassen som skriver ut -
// värdena för medlemsvariablerna
$obj->displayProp();

 

 

protected & private metoder

Det finns lägen då man inte vill att en viss metod ska vara tillgänglig utanför klassen (vilket man också ska eftersträva för att uppnå inkapsling, och med det avskilda delar), då begränsar man dess synlighet med nyckelordet; private eller protected:

class Dok_Test {
	protected $_var;
	protected $_val;
	private $_secret = 1234;

	public function displayProp() {/* ..innehåll */}
	public function setValues($newVal, $newVar) { /* ..innehåll */ }
	public function getValues() {/* ..innehåll */ }
	
	protected function setValue($val) {
		$this->_secret = $val;
	}
	/**
	* 
	* 
	*/
	public function initiateConnection($new_val) {
		if(is_numeric($new_val)) {
			$this::setValue(htmlspecialchars($new_val));
		}else {
			return;
		}
	}
}

Nu kan vi skapa en ny objekt och ange värden för båda medlemsvariablerna, eller lämna ut det:

// skapa ny objekt
$test = new Dok_Test();

// sätt värde för medlemsvariablerna
$test->setValue("Ny värde för _var", 1999);

// man använder print_r() och metoden getValues()
// för att skriva ut värdena från en array
print_r($test->getValue());

 

Vad vi har gått igenom hittils:

  • Det man kan göra med objekt står metoderna för och det man lagrar görs i egenskaper.
  • Alla egenskaper måste deklareras med, och föregås av en synlighetsnyckelord; public, protected eller private (detta gäller inte static medlemsvariabler som vi går igenom senare).
  • Att använda synlighetsnyckelord är valfritt när man definierar en metod, men det är rekommenderat att använda ett. Om inget anges, kommer metoden att ses som public.
  • Metod är ett ord för en funktion inne i en klass.
  • Man måste inkludera klassfilen för att kunna använda den. Man bör använda include_once eller require_once för att undvika att omdefiniera klassen, vilket utlöser en ”Fatal error”.
  • Skapa en instans av en klass, d.v.s. ett objekt med nyckelordet new.
  • $this variabeln; när den används i en klass, refererar till nuvarande objekt.
  • Använd -> operatorn för att komma åt en objekts metoder eller medlemsvariabler.
  • Om man försöker använda protected eller private medlemsvariabler från ett script utanför klassen, kommer scriptet att utlösa en ”Fatal error”.
  • Använd getter och setter metoder för att komma åt protected och private medlemsvariabler och metoder.

private – kan endast nås INIFRÅN klassen.

protected – kan nås från INOM klassen och av ÄRVDA klasser.

public – kan kommas åt från kod UTANFÖR och innanför klassen.

Detta gäller för funktioner och variabler.

Sätt standardvärden med konstruktor

Om du har programmerat i någon annan OOP språk som t.ex. Java, känner du säkert till konstruktor metoder. Dom heter oftast samma som klassen men i PHP har man ett enhetligt namn för den; construct (den hette samma som klassen i tidigare versioner av PHP).

construct anropas automatiskt när ett objekt skapas av en klass, och det är gotdytckligt vilken kod du lägger i metoden, men vanligen är det kod som initierar objektet genom att ge standardvärden till medlemsvariabler och anropa metoder.

Vi skriver in en __construct metod i vår klass:

class Dok_Test {
	protected $_var;
	protected $_val;

	/**
	* __construct() körs automatiskt vid -
	* skapande av ny instans av Dok_Test()
	* Den har default värden på båda medlemsvariablerna -
	* så att man kan utelämna dom vid skapande av det ny objektet
	*/
	public function __construct($val = 0, $var = '') {
		// initiera egenskaperna
		$this->_val = 0;
		$this->_var .= " som detta konkateneras vid skapande av nytt objekt";
	}

	public function setValues($newVal, $newVar) { /* ..innehåll */ }
	public function getValues() { /* ..innehåll */ }
	public function displayProp() { /* ..innehåll */ }
}

Observera att den har två understreck i början. Construct metoden används enbart vid skapande av ny objekt, så den bör inte returnera något.

 

__destruct()

Det finns även en __destruct() metod som anropas automatiskt när ett objekt förstörs. I metoden kan man då avsluta saker som inte behövs längre, som att stänga öppna filer, eller databaser.

$this & self::

Använd $this för att hänvisa till det aktuella objektet. Använd self för att hänvisa till den aktuella klassen. $this refererar till en instans av en klass. Men det finns också något som kallas statiskt tillstånd, vilket är densamma för alla förekomster av den klassen. self:: är åtkomst nyckelordet för dessa attribut och funktioner.

Definitioner:

  • Class – detta är en användardefinierad datatyp, som omfattar lokala funktioner samt tillhörande lokal data i form av egenskaper. Du kan tänka på en klass som en mall för att göra många exemplar av samma typ av objekt   (instans av klass).
  • Objekt – en individuell instans av datastrukturen som definieras av en klass. Du definierar en klass en gång och gör sedan så många objekt du behöver, vilka härrör från klassen. Objekt är också kända som instanser av klasser.
  • Objekt Ortienterad Programmering – betyder att man klumpar ihop funktionalitet som hör ihop i klasser som kan innehålla medlemsvariabler och funktioner som man modifierar instanser av klassen genom objekt som skapats av klasserna.
  • Medlemsvariabler – dessa är de variabler som definierats i en klass. Denna data kommer att vara osynlig utanför klassenen men kan nås via medlemsfunktioner. Dessa variabler kallas för egenskaper av objektet när ett objekt har skapats.
  • Medlemsfunktioner – dessa är funktioner definierade i en klass och används för att komma åt data som hör till  objektet.
  • Close coupling – kod som är sammanlänkad och beroende av de olika delarna i applikationen.
  • Loose coupling – kod som inte är beroende av varandra och skrivs i individuela block
  • Procedural  – betyder att koden läses rad efter rad i ett linjärt flöde
  • Arv – När en klass definieras genom utökning av en befintlig föräldraklass, så det kallas det för nedärvning (inheritance). En barn-klass ärver alla eller några medlemsfunktioner och variabler från dess förälder-klass.
  • Förälder-klass – en klass som en barn-klass ärver från. Detta kallas också en basklass eller superklass.
  • Barnklass – en klass som ärver från en annan klass. Detta kallas också en subklass eller deriverad klass.
  • Subklass – är en barnklass.
  • Superklass – är en förälderklass
  • Extend –  en barnklass extend en förälderklss.
  • Data Abstraktion – en representation av data där detaljerna av genomförandet är dolda (abstraherade).
  • Query – Syftar till söknings strängar som används för att hämta databas poster som matchar angivna kriterier, t.ex. ”SELECT * FROM users ORDER BY id”
  • Polymorfism – detta är ett objektorienterat koncept där samma funktion kan användas för olika ändamål. Till exempel funktionsnamn förblir desamma men det kan ta olika antal argument och kan göra olika uppgifter.

Menyer i WordPress

Att skapa menyer i WordPress kan vara rätt krångligt, och det finns ett antal sätt att skapa en, jag tänkte gå igenom ett par av mina favoriter. Vi börjar med att registrera menyer för olika platser, för du har väl tänkt på att man kan ha flera menyer i vissa teman? Så detta ska in i functions.php:!

// Registrera Menyer För Temat
add_action( 'init', 'register_my_menus' );

function register_my_menus() { 
	register_nav_menus(
		array(
			'header-menu' => __( 'Header Menu' ), 
			'sidebar-menu' => __( 'Sidebar Menu' ), 
			'footer-menu' => __( 'Footer Menu' )
		)
	);
}

 

wp_nav_menu

När du har lagt till koden på din functions.php, kommer du att märka att du kan hantera menypositioner. Du kan nu hitta dina nya menyer under:

http://din_sida/wp­-admin/nav-­menus.php

I funktionen wp_nav_menu som har 15 parametrar totalt att välja mellan, och här ser vi standard värdena för dom:

<?php
$defaults = array(
	'theme_location'  => '', /* header-menu, sidebar-menu och footer-menu */
	'menu'            => '',
	'container'       => 'nav', /* HTML-element som omgärdar listan */
	'container_class' => '', /* klass för HTML-element som omgärdar listan */
	'container_id'    => '', /* ID för HTML-element som omgärdar listan */
	'menu_class'      => 'menu',
	'menu_id'         => '',
	'echo'            => true,
	'fallback_cb'     => 'wp_page_menu',
	'before'          => '',
	'after'           => '',
	'link_before'     => '',
	'link_after'      => '',
	'items_wrap'      => '<ul id="%1$s" class="%2$s">%3$s</ul>',
	'depth'           => 0,
	'walker'          => ''
);
wp_nav_menu($defaults);
?>

 

Och dessa har alla en betydelse så klart:

  • $theme_location – Menyn som du vill visa (som registrerades i functions.php).
  • $menu – Kalla en meny med id, namn eller slug.
  • $container – Vad du vill omgärda ul elementet med, som t.ex. div eller nav.
  • $container_class – Klassen som läggs på $container.
  • $container_id – ID som läggs på $container.
  • $menu_class – Klassen som läggs på ul elementet i menyn.
  • $menu_id – The id to be applied to the ul element of the menu.
  • $echo – Om man ska echo menyn eller return det.
  • $fallback_cb – Om ingen meny finns, vilken fallback funktion som ska användas.
  • $before – Text innan ankar länken.
  • $after – Text efter ankar länken.
  • $link_before – Text innan länk-texten.
  • $link_after – Text efter länk-texten.
  • $depth – Hur många nivåer av meny hierarkin som ska visas.
  • $walker – Anpassad objekt.

Som tur är behöver man inte skriva in alla. För att ange vilken meny man anropar ska du använda $theme_location parametern, som syftar på det namn du registrerat i functions.php.

Till exempel, om vi använder exemplet från början (i functions.php), kan du nu lägga till följande kod till dina mallar för att visa huvudnavigering (header-menu):

// header-php
<?php wp_nav_menu(array('theme_location' => 'header-menu')); ?>

// sidebar.php
<?php wp_nav_menu(array('theme_location' => 'sidebar-menu')); ?>

// och till sist footer.php
<?php wp_nav_menu(array('theme_location' => 'footer-menu')); ?>

 

Som du ser har jag bara en parameter i funktionen, men vi kan enkelt lägga till flera, och jag tänkte att vi lägger till nav som ett omgärdande element och en klass main-menu till den:

// header.php
<?php 
wp_nav_menu(
	array(
		'theme_location' => 'header-menu',
		'container' => 'nav',
		'container_class' => 'main-menu'
	)
); 
?>

 

Klasserna ”current_page_item” & ”current-menu-item”

WordPress skapar automatisk ett antal klasser för navigationen, och om du kollar på källkoden för menyn vi precis skapade så hittar du liknande HTML-kod:

<nav class="header-menu">
	<ul id="menu-header-menu" class="menu">
		<li id="menu-item-63" class="menu-item menu-item-type-custom menu-item-object-custom current-menu-item current_page_item menu-item-home menu-item-63">
			<a href="http://localhost/wp/">Hemsida</a>
		</li>
		<li id="menu-item-60" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-60">
			<a href="http://localhost/wp/galleri">Galleri</a>
		</li>
	</ul>
</nav>

 

Som du ser blir det en massa klasser men två viktigaste är; ”current_page_item” och ”current-menu-item”, för med hjälp av dom kan vi styla menyknappen som är aktiv (sidan man är på), och ”menu-item-home” är specik för hemsidan.”menu-item” är en generell klass som kommer att skapas för varje <li> element, i alla menyer och resten är unika i installationen. Här är en lista på  standard klasser som WordPress skapar:

current_page_item 		– Stylar den aktuella sidan. 
current­-cat 			– Stylar den aktuella kategorin. 
menu­-item 			– Stylar alla andra menyalternativ. 
menu­-item­-type­-taxonomy 	– Stylar kategorilänkar. 
menu­-item­-type­-post_type 	– Stylar sidolänkar. 
menu­-item­-type­-custom 	        – Stylar anpassade objekt. 
menu­-item­-home 		        – Stylar hemsidan länken.

Man kan enkelt lägga till en egen klass för en enskild länk, genom att klicka på ”Panelinställningar” högst upp på sidan Menyer, då kommer en rullgardinsmeny att sänkas ner. Därifrån hittar du ett alternativ för att visa ”CSS Klasser” under rubriken ”Visa avancerade menyalternativ”:

Bild på "Panelinställningar" på sidan "Menyer"
”Panelinställningar” på sidan ”Menyer”

Nu kan du lägga till en klass under menyinställningar:

Bild på Admin Panelen » Menyer » CSS Klass
Admin Panelen » Menyer » CSS Klass

Exportera WordPress sida

Artikeln finns som PDF här – Exportera WordPress sida

Jag ska gå igenom en rätt avancerad metod för att manuellt exportera WordPress, och du bör ha testat att exportera med WordPress egen export funktion.

Om du har din gamla installation på en lokal dator så fungerar inte exportera funktionen inte korrekt för att den nya sidan på internet inte kan ladda ner bilder mm. från en lokal dator. Då kan man i stället exportera/importera all innehåll manuellt. Till att börja med ska du ska ha en ny, helt tom WordPress installation på målplatsen.

 

Fem steg…

Det finns fem steg i den här exporten:

  1. Installera en ny WordPress sida   » under din nya domän (skriv ner namnet på databasen du skapar för WordPress)
  2. Kopiera / ladda ner                       » tillägg, teman och uppladdningar från den gamla installationen (uppladdningar är alla mediafiler)
  3. Exportera WordPress databasen » från den gamla installationen
  4. Fixa till alla URL                            » i databasen med en textredigerare (ersätt gamla URL med nya)
  5. Importera databasen                    » till den nya installationen genom phpMyAdmin

 

Hämta tillägg, teman och uppladdningar

Du ska börja med att ladda ner/kopiera all innehåll från wp/wp-content/ (där wp står för själva WordPress installationen) från din gamla installation till din nya, d.v.s. ta dom tillägg som inte finns på den nya installationen och laddar upp dom till wp/wp-content/plugins/, sedan tar du hela mappen wp/wp-content/uploads (bilder plus andra mediafiler) och flyttar dom till wp/wp-content/ och till slut plockar du temat/teman från wp/wp-content/themes och flyttar dom till samma plats i den nya installationen.

Man kan göra flytten av filerna med en FTP klient som t.ex. FileZilla [1] eller logga in på webbplatsens kontrollpanel där du kan ladda upp filerna.

[1] Jämförelse av FTP klienter Wikipedia – http://en.wikipedia.org/wiki/Comparison_of_FTP_client_software

 

Exportera databasen

Om du går till den nya sidan och loggar in på admin-panelen och klickar på ”Media”, märker du att det inte finns några media-filer, och det beror på att WordPress inte vet om att dom finns än. För att fixa till det behöver du exportera databasen från den gamla installationen.

Nu måste du komma åt phpMyAdmin (du bör veta hur) som din gamla installationen använder, för att kunna exportera databasen. Du gör det antingen genom att starta servern (MAMP, XAMP m.fl.) och gå till http://localhost/phpMyAdmin/ eller på en MAMP, XAMP eller AMPPS server navigera dit från startsidan/menun, men om du har din sida uppe på nätet så får du logga dig in till kontrollpanelen på webbhotellet och där använda de verktyg som finns för phpMyAdmin.

När du öppnat phpMyAdmin klickar du på “Databases” och sedan väljer du databasen som tillhör den gamla installationen:

Screen-shot - välj databas i phpMyAdmin
Screen-shot: – välj databas i phpMyAdmin

Klicka nu på “Export”, och sedan för export metod väljer du “Custom – display all possible options”:

Screen-shot "custom export" i phpMyAdmin
Screen-shot: ”custom export” i phpMyAdmin

Se till att alla tabeller är valda (dom har grå bakgrund i så fall). Se nu till att “Save output to a file” är ikryssad, “Compression” är satt till “none” och att “Format” är SQL:

Screen-shot "Save output to file" i phpMyAdmin
Screen-shot: ”Save output to file” i phpMyAdmin

Nu skrollar du ner till “Object creation options” och kryssar i “Add DROP TABLE / VIEW / PROCEDURE / FUNCTION / EVENT statement” och ser till att “Add CREATE PROCEDURE / FUNCTION / EVENT statement” inte är ikryssad:

Screen-shot "Object creation options" i phpMyAdmin
Screen-shot: ”Object creation options” i phpMyAdmin

Och klicka på “Go” längst ner, då får du SQL tabellen (fil med .sql filtillägg) som en nedladdning, skapa genast en kopia av den för du ska endast arbeta med kopian så att det alltid finns ett skyddsnät!

 

Nu ska du ta reda på den exakta adressen till den gamla installationen och ersätta med adressen till den nya, så om du har den gamla installation under:

http://localhost/wordpress

och den nya under:

http://localhost/~d/labb_cms2/wordpress/wp

 

Öppna nu SQL-filen i en textredigerare som har sök och ersätt funktion, och börja med att söka efter:

http://localhost/wordpress

och ersätta med:

http://localhost/~d/labb_cms2/wordpress/wp

(Ja, du ska självklart byta till din egen adress)

 

EFTER det söker du efter ställen där det bara står:

/wordpress

och ersätta med:

/wp

OBS! Det är viktigt att du först söker efter hela URL adressen – http://localhost/wordpress – för om du skulle söka efter – /wordpress – först skulle länkarna gå sönder och det skulle inte gå att hitta dom efter det.

 

Importera databasen

Nu ska du logga in till kontrollpanelen för din nya installation och så navigerar du till phpMyAdmin letar upp rätt databas (och exporterar den precis likadant så att du har en backup). Vi ska radera alla tabeller från den nya databasen och sedan importera den gamla. Så när du valt alla tabeller klickar du på dropdown menun “With selected:” och väljer “Drop”.

Screen-shot Radera tabeller i phpMyAdmin
Screen-shot: Radera tabeller i nya installationen

Sedan bekräftar du ditt val och då är dom borta för gott!

Nu ska du klicka på “Import” och sedan “Browse for files” och navigera dig till och välja tabellen som du fixade adresserna i för att sedan klicka på “Go”.

Om du klickar på “Structure” fliken efter importen, så ska den gamla tabellen finnas där:

 

Screen-shot phpMyAdmin tabellen under "Structure"
Screen-shot: Gamla tabellerna under ”Structure”

 

 

Uppdatera databas

När du ska logga in kommer det att stå Database Update Required så du får uppdatera databasen genom att trycka på knappen “Update WordPress database”

 

Screen-shot: "Database Update Required"
Screen-shot: ”Database Update Required”

Sedan kan du logga in som normalt. Nu bör sidan fungera och allt borde vara som det en gång var, och du har lyckats att exportera WordPress! …eller?

 

Kolla alla länkar

Till sist ska du kolla noga så att allt har blivit rätt, genom att gå igenom sidor och inlägg för att se så att alla bilder syns och alla länkar till inlägg går dit dom ska och inte till den lokala installationen. Se även till att din menu pekar rätt och var uppmärksam på att du inte hamnar på http://localhost helt plötsligt för då har du missat en länk i den importerade databasen och får kanske söka igenom den noggrant. Själv hittade jag några ”trasiga” länkar och tog hand om dom direkt i inläggen genom att redigera dom.

 

Jag hoppas att den här artikeln gav dig något och ser fram emot ditt nästa besök. Daniel K