4-bo‘lim

Satrlar bilan ishlash

Qo'shtirnoq va apostrof farqi, qidirish va almashtirish, bo'lish va birlashtirish, UTF-8 va mb_ funksiyalari.

🕑 14 daqiqa o‘qish 📄 1 017 so‘z 👁 1 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Qo'shtirnoq va apostrof
  2. Heredoc va Nowdoc
  3. Asosiy funksiyalar
  4. UTF-8 va o'zbek harflari
  5. Bo'lish va birlashtirish
  6. Formatlash
  7. Amaliy misol: slug yasash
  8. Xulosa

Veb dasturlashda ishingizning katta qismi - matn. Forma ma'lumoti, URL, HTML, JSON - hammasi satr.

Qo'shtirnoq va apostrof #

PHP
// Har bir misol qat'iy turlar rejimida ishlaydi.
PHP
$ism = "Husanboy";
$yosh = 25;

// Qo'shtirnoq - o'zgaruvchilarni O'RNIGA QO'YADI
echo "Qo'shtirnoq: {$ism}, {$yosh} yosh\n";

// Apostrof - matnni AYNAN chiqaradi
echo 'Apostrof:   {$ism}, {$yosh} yosh' . "\n";

echo "\n";
// Maxsus belgilar faqat qo'shtirnoqda ishlaydi
echo "Qo'shtirnoqda \\t tabulyatsiya:\tmana\n";
echo 'Apostrofda \t tabulyatsiya:\tmana' . "\n";

echo "\n";
// Murakkab ifodalar uchun figurali qavs SHART
$mahsulot = ["nom" => "Klaviatura", "narx" => 350000];
echo "Massiv elementi: {$mahsulot['nom']}\n";
echo "Narxi: {$mahsulot['narx']} so'm\n";
Natija
Qo'shtirnoq: Husanboy, 25 yosh
Apostrof:   {$ism}, {$yosh} yosh

Qo'shtirnoqda \t tabulyatsiya:    mana
Apostrofda \t tabulyatsiya:\tmana

Massiv elementi: Klaviatura
Narxi: 350000 so'm
Qaysi birini tanlash
VaziyatTanlov
O'zgaruvchi qo'yish kerak"qo'shtirnoq"
\n, \t kerak"qo'shtirnoq"
Oddiy matn'apostrof'
Matnda $ bor (masalan narx belgisi)'apostrof'
HTML atributlari ichida'apostrof' qulayroq

Tezlik farqi amalda sezilmaydi - PHP 7 dan beri ikkalasi deyarli bir xil tez. Shuning uchun tanlovni tezlik emas, o'qish qulayligi bilan qiling.

Figurali qavs qoidasi:

PHP
echo "$ism";              // ishlaydi
echo "{$ism}";            // ishlaydi, aniqroq
echo "$massiv['kalit']";  // XATO
echo "{$massiv['kalit']}";// to'g'ri
echo "{$obyekt->usul()}"; // faqat shunday ishlaydi

Tavsiya: har doim {} qo'ying. U hech qachon zarar qilmaydi va qayerda o'zgaruvchi tugashini aniq ko'rsatadi.

Heredoc va Nowdoc #

PHP
$mijoz = "Malika";
$summa = 450000;

// Heredoc - qo'shtirnoq kabi ishlaydi (o'zgaruvchi qo'yiladi)
$xat = <<<MATN
    Hurmatli {$mijoz},

    Sizning buyurtmangiz qabul qilindi.
    To'lov summasi: {$summa} so'm.

    Hurmat bilan,
    Softromeda
    MATN;

echo $xat . "\n";

echo "\n" . str_repeat("=", 40) . "\n\n";

// Nowdoc - apostrof kabi (o'zgaruvchi qo'yilmaydi)
$shablon = <<<'SHABLON'
    Hurmatli {$mijoz},
    Summa: {$summa}
    SHABLON;

echo $shablon . "\n";
Natija
Hurmatli Malika,

Sizning buyurtmangiz qabul qilindi.
To'lov summasi: 450000 so'm.

Hurmat bilan,
Softromeda

========================================

Hurmatli {$mijoz},
Summa: {$summa}
PHP 7.3 dan beri yopuvchi belgini chekintirish mumkin

Yuqoridagi kodda MATN; qatori kod bilan bir xil darajada chekintirilgan - va PHP shu chekinishni avtomatik olib tashlaydi.

Eski PHP da yopuvchi belgi majburiy ravishda qator boshida turishi kerak edi:

PHP
    $xat = <<<MATN
Matn shu yerda boshlanadi
MATN;

Bu kodni juda xunuk qilardi. Endi esa heredoc blokini funksiya ichida ham chiroyli yozish mumkin.

Qoida: yopuvchi belgidagi chekinish har bir qatordan olib tashlanadi. Agar biror qator undan kamroq chekintirilgan bo'lsa - xato beradi.

Heredoc qayerda qulay: SQL so'rovlari, elektron xat shablonlari, uzun HTML bo'laklari.

Asosiy funksiyalar #

PHP
$matn = "  Zamonaviy PHP dasturlash  ";

printf("%-28s %s\n", "Asl (qavs ichida):", "[{$matn}]");
printf("%-28s %s\n", "trim:", "[" . trim($matn) . "]");
printf("%-28s %s\n", "ltrim:", "[" . ltrim($matn) . "]");
printf("%-28s %s\n", "rtrim:", "[" . rtrim($matn) . "]");

$t = trim($matn);
echo "\n";
printf("%-28s %d\n", "strlen (bayt):", strlen($t));
printf("%-28s %s\n", "strtoupper:", strtoupper($t));
printf("%-28s %s\n", "strtolower:", strtolower($t));
printf("%-28s %s\n", "ucfirst:", ucfirst(strtolower($t)));
printf("%-28s %s\n", "ucwords:", ucwords(strtolower($t)));

echo "\n";
printf("%-28s %s\n", "str_contains 'PHP':", str_contains($t, "PHP") ? "ha" : "yo'q");
printf("%-28s %s\n", "str_starts_with 'Zamon':", str_starts_with($t, "Zamon") ? "ha" : "yo'q");
printf("%-28s %s\n", "str_ends_with 'lash':", str_ends_with($t, "lash") ? "ha" : "yo'q");
printf("%-28s %d\n", "strpos 'PHP':", strpos($t, "PHP"));
printf("%-28s %s\n", "substr(0, 9):", substr($t, 0, 9));
printf("%-28s %s\n", "str_replace:", str_replace("PHP", "PHP 8", $t));
Natija
Asl (qavs ichida):           [  Zamonaviy PHP dasturlash  ]
trim:                        [Zamonaviy PHP dasturlash]
ltrim:                       [Zamonaviy PHP dasturlash  ]
rtrim:                       [  Zamonaviy PHP dasturlash]

strlen (bayt):               24
strtoupper:                  ZAMONAVIY PHP DASTURLASH
strtolower:                  zamonaviy php dasturlash
ucfirst:                     Zamonaviy php dasturlash
ucwords:                     Zamonaviy Php Dasturlash

str_contains 'PHP':          ha
str_starts_with 'Zamon':     ha
str_ends_with 'lash':        ha
strpos 'PHP':                10
substr(0, 9):                Zamonaviy
str_replace:                 Zamonaviy PHP 8 dasturlash
strpos natijasini !== false bilan tekshiring

strpos satr topilmasa false, birinchi belgida topilsa 0 qaytaradi. Va 0 PHP da bo'sh hisoblanadi:

PHP
if (strpos($matn, "Zamon")) {     // XATO
    // "Zamon" 0-o'rinda - shart YOLG'ON bo'ladi
}

if (strpos($matn, "Zamon") !== false) {   // to'g'ri
    // ishlaydi
}

Bu PHP dagi eng mashhur tuzoqlardan biri. U yillar davomida minglab xatoga sabab bo'lgan.

PHP 8 buni hal qildi. Endi shunchaki yozing:

Eski usulYangi (PHP 8)
strpos($a, $b) !== falsestr_contains($a, $b)
substr($a, 0, strlen($b)) === $bstr_starts_with($a, $b)
substr($a, -strlen($b)) === $bstr_ends_with($a, $b)

O'ng ustundagilar aniq bool qaytaradi va hech qanday tuzoq yo'q. strpos ni faqat o'rnini bilish kerak bo'lganda ishlating.

UTF-8 va o'zbek harflari #

PHP
$uz = "O'zbekiston";
$rus = "Привет";

echo "strlen('{$uz}')      = " . strlen($uz) . " bayt\n";
echo "mb_strlen('{$uz}')   = " . mb_strlen($uz) . " belgi\n";

echo "\n";
echo "strlen('{$rus}')        = " . strlen($rus) . " bayt\n";
echo "mb_strlen('{$rus}')     = " . mb_strlen($rus) . " belgi\n";

echo "\n";
echo "Kirill harflar ikki baytdan iborat - shuning uchun farq bor.\n";

echo "\n";
echo "Noto'g'ri kesish (substr):    " . substr($rus, 0, 5) . "|\n";
echo "To'g'ri kesish (mb_substr):   " . mb_substr($rus, 0, 5) . "|\n";

echo "\n";
echo "strtoupper (kirill uchun ishlamaydi): " . strtoupper($rus) . "\n";
echo "mb_strtoupper (to'g'ri):              " . mb_strtoupper($rus) . "\n";
Natija
strlen('O'zbekiston')      = 11 bayt
mb_strlen('O'zbekiston')   = 11 belgi

strlen('Привет')        = 12 bayt
mb_strlen('Привет')     = 6 belgi

Kirill harflar ikki baytdan iborat - shuning uchun farq bor.

Noto'g'ri kesish (substr):    Пр�|
To'g'ri kesish (mb_substr):   Приве|

strtoupper (kirill uchun ishlamaydi): Привет
mb_strtoupper (to'g'ri):              ПРИВЕТ
Matn foydalanuvchidan kelsa - mb_ ishlating

PHP ning oddiy satr funksiyalari baytlar bilan ishlaydi, belgilar bilan emas.

Lotin harflari uchun bu farq yo'q - ular bir baytdan iborat. Lekin kirill, arab, xitoy yoki emoji uchun bitta belgi 2-4 bayt egallaydi.

Natijada substr belgini o'rtasidan kesib yuborishi mumkin - va ekranda buzuq belgi chiqadi.

OddiyKo'p baytli
strlenmb_strlen
substrmb_substr
strtouppermb_strtoupper
strtolowermb_strtolower
strposmb_strpos
str_splitmb_str_split

Qachon qaysi biri:

VazifaFunksiya
Fayl hajmini hisoblashstrlen (bayt kerak)
Matnni qisqartirishmb_substr
Belgilar sonini sanashmb_strlen
Parol uzunligini tekshirishmb_strlen

mb_ funksiyalari mbstring kengaytmasini talab qiladi - 2-bo'limda uni tekshirgan edik.

Bayt va belgi - bir xil narsa emas "PHP" - lotin P H P 3 belgi 3 bayt strlen = mb_strlen "Привет" - kirill П 2 bayt р 2 bayt и 2 bayt 6 belgi 12 bayt strlen = 12, mb_strlen = 6 substr(3) nima qiladi Lotin: "PHP" -> butun belgilar Kirill: 3 bayt = 1.5 belgi Belgi O'RTASIDAN kesiladi Natija: ekranda buzuq belgi Yechim: mb_substr O'zbek lotin alifbosida ham tuzoq bor Agar apostrof ' emas, tipografik ' ishlatilsa - u ham ko'p baytli belgi. Oltin qoida Foydalanuvchi matni bilan ishlaganda har doim mb_ versiyasini tanlang.
Bir belgi bir bayt degani emas - bu xatoning eng keng tarqalgan manbai

Bo'lish va birlashtirish #

PHP
$qator = "klaviatura,sichqoncha,monitor,quloqchin";

$royxat = explode(",", $qator);
echo "Elementlar soni: " . count($royxat) . "\n";
foreach ($royxat as $i => $element) {
    echo "  [{$i}] {$element}\n";
}

echo "\n";
echo "Qayta birlashtirish: " . implode(" | ", $royxat) . "\n";

echo "\n";
// Cheklangan bo'lish
$sana = "2024-09-01";
[$yil, $oy, $kun] = explode("-", $sana);
echo "Yil: {$yil}, Oy: {$oy}, Kun: {$kun}\n";

echo "\n";
// Bo'sh elementlarni tozalash
$tartibsiz = "olma, , anor,  ,behi";
$toza = array_values(array_filter(
    array_map("trim", explode(",", $tartibsiz)),
    static fn(string $x): bool => $x !== ""
));
echo "Tozalangan: " . implode(", ", $toza) . "\n";
echo "Soni: " . count($toza) . "\n";
Natija
Elementlar soni: 4
  [0] klaviatura
  [1] sichqoncha
  [2] monitor
  [3] quloqchin

Qayta birlashtirish: klaviatura | sichqoncha | monitor | quloqchin

Yil: 2024, Oy: 09, Kun: 01

Tozalangan: olma, anor, behi
Soni: 3

Formatlash #

PHP
$narx = 1234567.891;

echo "number_format:\n";
echo "  standart:    " . number_format($narx) . "\n";
echo "  2 xona:      " . number_format($narx, 2) . "\n";
echo "  o'zbekcha:   " . number_format($narx, 2, ",", " ") . " so'm\n";

echo "\n";
echo "printf/sprintf:\n";
printf("  %%d butun:       %d\n", $narx);
printf("  %%.2f kasr:      %.2f\n", $narx);
printf("  %%10.2f o'ngga:  %10.2f\n", 42.5);
printf("  %%-10s chapga:   [%-10s]\n", "matn");
printf("  %%05d nol bilan: %05d\n", 42);
printf("  %%x o'n oltilik: %x\n", 255);
printf("  %%b ikkilik:     %b\n", 10);

echo "\n";
$satr = sprintf("Buyurtma #%04d - %s", 7, "tayyor");
echo "sprintf natijasi: {$satr}\n";

echo "\n";
echo "str_pad bilan jadval:\n";
$qatorlar = [["Non", 4000], ["Sut", 12500], ["Shakar", 9800]];
foreach ($qatorlar as [$nom, $narxi]) {
    echo "  " . str_pad($nom, 12, ".") . str_pad((string) $narxi, 8, " ", STR_PAD_LEFT) . "\n";
}
Natija
number_format:
  standart:    1,234,568
  2 xona:      1,234,567.89
  o'zbekcha:   1 234 567,89 so'm

printf/sprintf:
  %d butun:       1234567
  %.2f kasr:      1234567.89
  %10.2f o'ngga:       42.50
  %-10s chapga:   [matn      ]
  %05d nol bilan: 00042
  %x o'n oltilik: ff
  %b ikkilik:     1010

sprintf natijasi: Buyurtma #0007 - tayyor

str_pad bilan jadval:
  Non.........    4000
  Sut.........   12500
  Shakar......    9800
printf va sprintf farqi
FunksiyaNima qiladi
printfEkranga chiqaradi
sprintfSatr sifatida qaytaradi
vsprintfArgumentlarni massivdan oladi

Eng ko'p ishlatiladigan belgilar:

BelgiMa'nosi
%dButun son
%sSatr
%fKasr son
%.2fIkki xonali kasr
%05dNol bilan to'ldirilgan
%-10sChapga tekislangan
%%Foiz belgisining o'zi

Diqqat: printf foydalanuvchi kiritgan matnni format satri sifatida ishlatmang:

PHP
printf($foydalanuvchi_matni);        // XAVFLI
printf("%s", $foydalanuvchi_matni);  // to'g'ri

Birinchi holatda matndagi %s belgilari format ko'rsatkichi deb qabul qilinadi va kutilmagan natija beradi.

Amaliy misol: slug yasash #

PHP
function slugYasa(string $matn): string
{
    $matn = mb_strtolower($matn, "UTF-8");

    // 1-qadam: APOSTROFLARNI butunlay olib tashlaymiz.
    // Ularni tire qilib qoldirsak, "ta'lim" -> "ta-lim" bo'lardi.
    // O'zbek tilida apostrof harfning bir qismi, so'z ajratgichi emas.
    $apostroflar = ["'", "\u{2018}", "\u{2019}", "\u{02BB}", "\u{02BC}"];
    $matn = str_replace($apostroflar, "", $matn);

    // 2-qadam: qolgan hamma narsani tire bilan almashtiramiz
    $matn = preg_replace("/[^a-z0-9]+/u", "-", $matn) ?? "";
    $matn = trim($matn, "-");

    return $matn === "" ? "sahifa" : $matn;
}

$sarlavhalar = [
    "Zamonaviy PHP dasturlash",
    "O'zbekistonda IT ta'lim",
    "Ma'lumotlar bazasi: PDO bilan ishlash",
    "   Bo'sh   joylar   ko'p   ",
    "!!!",
];

foreach ($sarlavhalar as $s) {
    printf("%-42s -> %s\n", "\"{$s}\"", slugYasa($s));
}
Natija
"Zamonaviy PHP dasturlash"                 -> zamonaviy-php-dasturlash
"O'zbekistonda IT ta'lim"                  -> ozbekistonda-it-talim
"Ma'lumotlar bazasi: PDO bilan ishlash"    -> malumotlar-bazasi-pdo-bilan-ishlash
"   Bo'sh   joylar   ko'p   "              -> bosh-joylar-kop
"!!!"                                      -> sahifa
Apostrof - o'zbek matnidagi asosiy tuzoq

Slug funksiyasini birinchi marta yozganda apostroflar maxsus ishlov olmagan edi va natija shunday chiqqandi:

SarlavhaNoto'g'ri natija
O'zbekistonda IT ta'limozbekistonda-it-ta-lim
Ma'lumotlar bazasima-lumotlar-bazasi

ta'lim ta-lim ga aylanib qolgan: apostrof so'zni ikkiga bo'lib yuborgan.

Sabab shundaki, apostrof o'zbek tilida harfning bir qismi - so'z chegarasi emas. Shuning uchun uni tire bilan almashtirish emas, butunlay olib tashlash kerak.

Ishni yanada chigallashtiradigan narsa - apostrofning bir necha xil yunikod belgisi bor va ular ko'zga bir xil ko'rinadi:

KodNomiQayerdan keladi
U+0027Oddiy apostrofKlaviaturadan
U+2018Chap tirnoqWord avtomatik qo'yadi
U+2019O'ng tirnoqWord avtomatik qo'yadi
U+02BBTutuq belgisiTo'g'ri o'zbek imlosi
U+02BCYumshatish belgisiYunikod tavsiyasi

Foydalanuvchi matnni Word dan nusxa qilsa, u yerda U+2019 bo'ladi - va oddiy ' bilan taqqoslash ishlamaydi. Kod to'g'ri ko'rinadi, lekin natija xato.

Shuning uchun yuqoridagi funksiya ularning hammasini bir vaqtda olib tashlaydi. O'zbek tilidagi sayt yozayotgan bo'lsangiz, bu ro'yxatni eslab qoling.

Amaliy topshiriq
  1. Bir xil matnni qo'shtirnoq va apostrofda chiqarib solishtiring.
  2. Massiv elementini qo'shtirnoq ichida {} siz chiqarishga urinib ko'ring.
  3. Heredoc bilan uch qatorli xat shabloni yozing.
  4. Nowdoc bilan xuddi shuni takrorlang - farqni ko'ring.
  5. strpos natijasini if da !== false siz tekshiring - nima bo'ladi?
  6. Uni str_contains ga almashtiring.
  7. Kirill matn uchun strlen va mb_strlen ni solishtiring.
  8. substr va mb_substr bilan kirill matnni kesib ko'ring.
  9. explode va implode bilan CSV qatorini qayta yig'ing.
  10. number_format bilan narxni o'zbekcha formatda chiqaring.

Xulosa #

  • Qo'shtirnoq o'zgaruvchini o'rniga qo'yadi, apostrof matnni aynan chiqaradi.
  • Satr ichida har doim {$ozgaruvchi} shaklini ishlating - u hech qachon adashtirmaydi.
  • Heredoc qo'shtirnoq kabi, Nowdoc apostrof kabi ishlaydi.
  • PHP 7.3 dan beri heredoc yopuvchi belgisini chekintirish mumkin.
  • strpos topilmasa false, birinchi belgida topilsa 0 qaytaradi - !== false bilan tekshiring.
  • PHP 8 da str_contains, str_starts_with, str_ends_with bor - ular tuzoqsiz.
  • Oddiy satr funksiyalari bayt bilan, mb_ funksiyalari belgi bilan ishlaydi.
  • Kirill harfi 2 bayt egallaydi - substr uni o'rtasidan kesib buzadi.
  • Foydalanuvchi matni bilan ishlaganda har doim mb_ versiyasini tanlang.
  • printf chiqaradi, sprintf qaytaradi.
  • Foydalanuvchi matnini format satri sifatida ishlatmang: printf("%s", $matn).
  • O'zbek matnida apostrof harfning qismi - slug yasashda uni tire qilmang, o'chiring.
  • Apostrofning bir necha yunikod varianti bor (U+0027, U+2019, U+02BB) - hammasini hisobga oling.

Keyingi bo'limda massivlar - PHP ning eng kuchli ma'lumot tuzilmasi bilan tanishamiz.

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.