W tym odcinku poznajemy funkcje formatujące PHP – sprintf a także printf. Poznamy ich budowę i zastosowanie, zasymulujemy ich użycie wewnątrz frameworka takiego jak WordPress. Lekcja krótka, skupiająca się na zagadnieniu formatowania w PHP.

Sprintf – przykład użycia

Oto przykład użycia sprintf z dokumentacji PHP:

<?php
$num = 5;
$location = 'tree';

$format = 'There are %d monkeys in the %s';
echo sprintf($format, $num, $location);
?>

Mamy format, „%d” oznaczający liczbę (digit), „%s” oznaczający napis (string) oraz formatowany napis, który wyświetlamy.

Dodam, że format zazwyczaj nie jest osobną zmienną:

<?php
$num = 5;
$location = 'tree';
echo sprintf('There are %d monkeys in the %s', $num, $location);
?>

Dodam, że możemy bawić się kolejnością przy naszym formacie.

<?php
$num = 5;
$location = 'tree';
$format = 'The %2$s contains %1$d monkeys';
echo sprintf($format, $num, $location);
//The tree contains 5 monkeys
?>

Czyli „%2$s” oznacza – wstaw drugą zmienną-string. Zaś „%1$d” oznacza wstaw pierwszą zmienną-digit.

Nie musi nam się ten zapis podobać, ale tak to działa. Moglibyśmy teraz bawić się tym sprintf w nieskończoność, ale ktoś może zadać pytanie – po co mi to?

I na to pytanie nie ma dobrej odpowiedzi, sprintf „błyszczy”, gdy w jakiś bystry sposób użyjemy go wewnątrz jakiegoś frameworku, oszczędzając sobie pracy.

Myślę, że możemy jakiś framework, na przykład WordPress, na szybko sobie zasymulować.

Mini-projekt – pseudowordpress

Tworzymy funkcję get_the_ID(), która w takim WordPressie zwracałaby ID danego posta. U nas będzie zwracać liczbę z góry określoną, ponieważ tylko tworzymy pewną symulację pewnych funkcjonalności wordpressa:

<?php
function get_the_ID(){
    return "11";
}
?>

Okej, mamy to. Teraz funkcja the_ID(), która wyświetla ID posta:

<?php
function get_the_ID(){
    return "11";
}
function the_ID(){
    echo get_the_ID();
}
?>

Dodam, że funkcja the_ID() w WordPressie wygląda identycznie, co do znaku. Ale mniejsza.

Pod spodem dodajemy kolejną funkcję, get_the_title() – ma symulować zwracanie tytułu naszego posta:

<?php
//(...)
function get_the_title(){
    return "PHP tutorial - vol. 10";
}
?>

Teraz najtrudniejsza funkcja – the_title. Ma wyświetlić title, a także być w stanie przyjąć argumenty before i after do wyświetlania czegoś przed i po tytule.

Na początek:

function the_title($before=null, $after=null){
    echo get_the_title();
}

Okej, już jakoś wygląda, ale ignoruje before i after. Dodajmy obsługę tychże:

function the_title($before=null, $after=null){
    $title = get_the_title();
    if(!is_null($before)) 
        $title = $before . $title;
    if(!is_null($after)) 
        $title = $title . $after;
    echo $title;
}

Do title zapisujemy tytuł, wyświetlamy go. Wcześniej sprawdzamy czy istnieje before i after i before doklejamy do tytułu z przodu, after zaś – z tyłu.

Nasz pseudoframework wygląda teraz tak:

<?php
function get_the_ID(){
    return "11";
}
function the_ID(){
    echo get_the_ID();
}
function get_the_title(){
    return "PHP tutorial - vol. 10";
}
function the_title($before=null, $after=null){
    $title = get_the_title();
    if(!is_null($before)) 
        $title = $before . $title;
    
    if(!is_null($after)) 
        $title = $title . $after;
    echo $title;
}
?>

Zabawa pseudowordpressem

Teraz zabawimy się naszym frameworkiem. Spróbujmy wypisać <h3> z tytułem naszego posta:

<?php
function get_the_ID(){
    return "11";
}
function the_ID(){
    echo get_the_ID();
}
function get_the_title(){
    return "PHP tutorial - vol. 10";
}
function the_title($before=null, $after=null){
    $title = get_the_title();
    if(!is_null($before)) 
        $title = $before . $title;
    
    if(!is_null($after)) 
        $title = $title . $after;
    echo $title;
}
?>
<h3><?php the_title();?></h3>

Działa. A teraz spróbujmy to zrobić nie wychodząc z PHP:

<?php
function get_the_ID(){
    return "11";
}
//(...)
the_title("<h3>", "</h3>");
?>

Jak najbardziej działa, <h3> jest tutaj argumentem before, </h3> argumentem after.

Zabawmy się w coś takiego:

<?php
function get_the_ID(){
    return "11";
}
//(...)
?>
<h3 id="post-<?php the_ID(); ?>"><?php the_title(); ?></h3>

Teraz nasz post dostaje ID o nazwie „post-” oraz ID zwrócone przez funkcję, wewnątrz <h3> mamy zaś tytuł:

<h3 id="post-11">PHP tutorial - vol. 10</h3>

I teraz pytanie – jak osiągnąć to samo, ale używając naszej funkcji the_title() wewnątrz PHP? Z argumentami before i after?

I tutaj przychodzi nam z pomocą sprintf():

<?php
function get_the_ID(){
    return "11";
}
//(...)
the_title(
    sprintf('<h3 id="post-%s">', get_the_ID()),
    "</h3>"
);
?>

Do the_title przekazaliśmy argumenty before i after. After to tag zamykający </h3> zaś before – sprintf, gdzie tworzymy tag <h3> z dynamicznie generowanym ID, do którego wrzucamy to, co get_the_ID() zwraca.

Dostajemy:

<h3 id="post-11">PHP tutorial - vol. 10</h3>

W takich właśnie przypadkach funkcja sprintf błyszczy najbardziej.

Printf – sprintf wyświetlający

Poza funkcją sprintf, która zwraca formatowany string, mamy też funkcję printf, która od razu taki napis wyświetla. Porównajmy:

<?php
$num = 5;
$location = 'tree';

$format = 'There are %d monkeys in the %s';
echo sprintf($format, $num, $location);
printf($format, $num, $location);
//There are 5 monkeys in the tree
//There are 5 monkeys in the tree
?>

Printf to takie „echo sprintf”.

Printf – przykład użycia

Dalej będziemy sobie wyobrażać, że pracujemy w frameworku WordPress, który posiada funkcję get_the_modified_date(), która zwraca datę modyfikacji posta w podanym formacie (format może być różny, może zwrócić datę albo czas, tak, jak jej nakażemy).

Oczywiście udajemy tylko działanie tej funkcji, więc zwracać będzie aktualną datę, nie mamy przecież postów:

<?php
function get_the_modified_date($format){
    return date($format);
}
echo get_the_modified_date('F j, Y');
//April 5, 2024
echo "</br>";
echo get_the_modified_date("'g:i a'");
//'1:05 pm
?>

Funkcja zwraca nam dzisiejszą datę i czas według takiego formatu (akurat nie naszego, ale mniejsza). Będziemy jednak dla przykładu udawać, że pracujemy w WordPressie i to jest data jakiegoś postu.

Teraz chcemy uprościć poniższy zapis używając printf:

<?php
function get_the_modified_date($format){
    return date($format);
}
?>
<p>Modified: <?php echo get_the_modified_date('F j, Y');?> at <?php echo get_the_modified_date("'g:i a'");?></p>

Zapis, który zwraca:

<p>Modified: April 5, 2024 at '1:08 pm'</p>

Cóż, proste:

<?php
function get_the_modified_date($format){
    return date($format);
}
?>
<p>
    <?php printf(
        "Modified %s at %s",
        get_the_modified_date( 'F j, Y' ),
	    get_the_modified_date( 'g:i a' )
    ); ?>
</p>

Dostajemy:

<p>Modified April 5, 2024 at 1:10 pm</p>

Może printf i sprintf to nie są najłatwiejsze funkcje, ale już widzimy, że jeżeli je znamy i mamy pomysł, jak ich użyć – możemy dzięki nim pisać ciekawe i całkiem przyjazne kody.

Temat może i krótki, ale na pewno nie taki łatwy w odbiorze, więc na tym ćwiczeniu poprzestańmy.

Zobaczmy i przeanalizujmy raz jeszcze jak to działa. Ja tylko dodam, że te dwa kody z naszych ćwiczeń to jest kod w 100% brany z pracy w WordPressie, tylko nasze funkcje są tutaj „udawane”.

Do następnego razu.