Baza modelek Glamour Models: Modelki, Fotomodelki, Hostessy
Pokazywanie postów oznaczonych etykietą PHP. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą PHP. Pokaż wszystkie posty

poniedziałek, 28 lutego 2022

Regex Laziness Instead of Greediness

Przykład użycia "Laziness Instead of Greediness": ".+?"
https://www.regular-expressions.info/repeat.html

<?php

$h='<ul>

<li>ps</li>
<li>ps</li>
<li class="klasa1 klasa2
klasa2
" >xyz</li>

<li>ps</li>
</ul>';

$pattern = '/(.*)(\<li.+?(klasa2).+?\<\/li\>)(.*)/s';
$replacement = '${1}<li>tu jest podmiana</li>${4}';
      
 
echo preg_replace($pattern, $replacement, $h);  


Wynik:

<ul>

<li>ps</li>
<li>ps</li>
<li>tu jest podmiana</li>

<li>ps</li>
</ul>

wtorek, 31 sierpnia 2021

SOLID Principles in Laravel: 5 Examples

środa, 6 stycznia 2016

Jak stworzyć archiwum Zip w PHP

Przykład rekursywnego tworzenia archiwum Zip:

<?php

$directory = 'files';

$path = __DIR__ . '/' . $directory;
$filename  = sprintf('%s.zip', $path);


$zip = new ZipArchive;
$zip->open($filename, ZipArchive::CREATE);

$files = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($path),
    RecursiveIteratorIterator::LEAVES_ONLY
);

foreach ($files as $name => $file) {
    if (! $file->isDir()) {
        $filePath = $file->getRealPath();
 
        $relativePath = substr($filePath, strlen($path) + 1);
 
        $zip->addFile($filePath, $relativePath);
    }
}

$zip->close();

środa, 31 grudnia 2014

Pobranie poprzedniego i następnego rekordu dowolnego zapytania w MySQL

Poniższe funkcje są przykładem, jak pobrać sąsiadujące wiersze w dowolnym zapytaniu z uwzględnieniem sortowania:

public function getPrevItem($id, $onlyActive = true, $categoryId = null) {
    $where = ' WHERE 1 = 1 ';
    $sqlParams = array();

    if ($onlyActive) {
        $where .= ' AND a.`active` = 1 AND c.`active` = 1 ';
    }

    if ($categoryId !== null) {
        $where .= ' AND a.id_category = ? ';
        $sqlParams[] = $categoryId;
    }

    $this->getSql()->query("SET @item_offset = -1");
    $sql = "SELECT * FROM (
                SELECT @item_offset := @item_offset + 1 AS `item_offset`, id
                FROM (
                    SELECT a.id
                    FROM  `articles` a
                    JOIN `articles_category` c ON c.id = a.id_category
                    $where
                    ORDER BY a.`pos` DESC, a.`id` DESC
                ) AS x
            ) AS t WHERE t.id = ?";

    $itemOffset = (int) $this->getSql()->value($sql, array_merge($sqlParams, array($id)));
    if ($itemOffset == 0) {
        return false;
    }

    $prevOffset = $itemOffset - 1;
    $sql = "SELECT a.*, c.name AS category_name, c.slug AS category_slug
            FROM `articles` a
            JOIN `articles_category` c ON c.id = a.id_category
            $where
            ORDER BY a.`pos` DESC, a.`id` DESC
            LIMIT 1
            OFFSET $prevOffset";

    $prev = $this->getSql()->one($sql);
    return $prev;
}

public function getNextItem($id, $onlyActive = true, $categoryId = null) {
    $where = ' WHERE 1 = 1 ';
    $sqlParams = array();

    if ($onlyActive) {
        $where .= ' AND a.`active` = 1 AND c.`active` = 1 ';
    }

    if ($categoryId !== null) {
        $where .= ' AND a.id_category = ? ';
        $sqlParams[] = $categoryId;
    }

    $this->getSql()->query("SET @item_offset = -1");
    $sql = "SELECT * FROM (
                SELECT @item_offset := @item_offset + 1 AS `item_offset`, id
                FROM (
                    SELECT a.id
                    FROM  `articles` a
                    JOIN `articles_category` c ON c.id = a.id_category
                    $where
                    ORDER BY a.`pos` DESC, a.`id` DESC
                ) AS x
            ) AS t WHERE t.id = ?";

    $itemOffset = (int) $this->getSql()->value($sql, array_merge($sqlParams, array($id)));

    $nextOffset = $itemOffset + 1;
    $sql = "SELECT a.*, c.name AS category_name, c.slug AS category_slug
            FROM `articles` a
            JOIN `articles_category` c ON c.id = a.id_category
            $where
            ORDER BY a.`pos` DESC, a.`id` DESC
            LIMIT 1
            OFFSET $nextOffset";

    $next = $this->getSql()->one($sql);
    return $next;
}


Legenda:
$this->getSql()->query() - wykonuje zapytanie
$this->getSql()->value() - zwraca wartość pierwszej kolumny w pierwszym rekordzie wyniku zapytania
$this->getSql()->one() - zwraca jeden rekord zapytania

niedziela, 16 września 2012

Generowanie struktury drzewiastej do testów

Jak wygenerować tablicę, która będzie reprezentować strukturę drzewiastą?

Pomocna będzie funkcja do generowania losowych wartości tekstowych:
function randomText(){
 $ch = range('a', 'z');
 $count = count($ch);
 $length = rand(5, 10);
 $text = '';
 
 for($i=0; $i < $length; $i++){
  $text .= $ch{rand(0, $count-1)};
 }
 
 return $text;
}

Utwórzmy klasę Tree, która będzie miała trzy prywatne właściwości określające wygenerowane drzewo, liczbę poziomów drzewa oraz liczbę gałęzi na każdym poziomie.
Do metody Tree::makeTree() przekazujemy wartości, które określą nam wielkość drzewa.
W końcu generujemy rekurencyjnie drzewo w prywatnej metodzie Tree::_makeTree(). Wartości przekazywane do tej metody to aktualny poziom, numer gałęzi na poziomie oraz numer węzła w drzewie, tzn. klucz w tablicy rodzica.
class Tree{
 private $tree; // wygenerowane drzewo
 private $levels; // liczba poziomów drzewa
 private $branches; // liczba gałęzi na każdym poziomie
 
 public function makeTree($levels, $branches){
  $this->tree = array();
  $this->levels = $levels;
  $this->branches = $branches;
  
  $this->_makeTree();
 }
 
 private function _makeTree($level = 0, $branch = 0, $id = null){
  if ($level > $this->levels) {
   return;
  }
  
  $this->tree[] = array('value' => randomText(), 'parent' => $id);
  
  end($this->tree);
  $id = key($this->tree);
  
  for($i=0; $i < $this->branches; $i++) {
   $this->_makeTree($level+1, $i, $id);
  }
 }
 
 public function getTree(){
  return $this->tree;
 } 
}

Aby wartości w drzewie miały za każdym razem takie same wartości, można ustawić generator liczb losowych.
srand(0);
$t = new Tree();
$t->makeTree(3,2);
var_dump($t->getTree());

Te ustawienia wygenerują tablicę o tej strukturze:
array
  0 => 
    array
      'value' => string 'eifefuq' (length=7)
      'parent' => null
  1 => 
    array
      'value' => string 'yknjklv' (length=7)
      'parent' => int 0
  2 => 
    array
      'value' => string 'fovima' (length=6)
      'parent' => int 1
  3 => 
    array
      'value' => string 'rtnuteg' (length=7)
      'parent' => int 2
  4 => 
    array
      'value' => string 'miagkiylls' (length=10)
      'parent' => int 2
  5 => 
    array
      'value' => string 'xbpvmgosn' (length=9)
      'parent' => int 1
  6 => 
    array
      'value' => string 'tqwrsjw' (length=7)
      'parent' => int 5
  7 => 
    array
      'value' => string 'ocjmxpr' (length=7)
      'parent' => int 5
  8 => 
    array
      'value' => string 'uarkvdrq' (length=8)
      'parent' => int 0
  9 => 
    array
      'value' => string 'coehs' (length=5)
      'parent' => int 8
  10 => 
    array
      'value' => string 'nkdupaci' (length=8)
      'parent' => int 9
  11 => 
    array
      'value' => string 'hvcjublmpy' (length=10)
      'parent' => int 9
  12 => 
    array
      'value' => string 'gihucb' (length=6)
      'parent' => int 8
  13 => 
    array
      'value' => string 'zzkpck' (length=6)
      'parent' => int 12
  14 => 
    array
      'value' => string 'nbjtsdg' (length=7)
      'parent' => int 12

wtorek, 21 lutego 2012

Miniaturki automatycznie zapisane na serwerze

Masz zdjęcia normalnych rozmiarów, jednak nie chcesz przerabiać wszystkich na miniatury.
Można za pomocą CSS lub atrybutów width i height zmniejszyć ich wymiary na ekranie, ale ich rozmiar będzie nadal tak duży, jak dużego zdjęcia, co powoduję że się dłużej ładują.

Pokażę trick wykorzystujący JavaScript/JQuery, .htaccess/mod_rewrite i oczywiście PHP, który będzie tworzył miniatury w locie i zapisywał je na serwerze, gdy tylko zdjęcie zostanie wyświetlone za pierwszym razem.

czwartek, 9 lutego 2012

Jak dodać unikalny ciąg znaków do rekordu w bazie danych

Pokażę sposób na wstawienie unikalnego ciągu znaków do tabeli w bazie danych.

Załóżmy, że mamy taką tabelę:
user
---------------------
id INT PRIMARY KEY AUTO_INCREMENT
hash VARCHAR DEFAULT NULL
data TEXT
gdzie id jest kluczem głównym, zatem indeksem unikalnym,
hash ma być unikalnym ciągiem znaków - na początku niech posiada wartość NULL,
oraz data - jakieś dane.

wtorek, 24 stycznia 2012

Zmiana kolejności kluczy w tablicy 2-wymiarowej

Przy uploadzie tablicy plików otrzymujemy taką tablicę 2-wymiarową:

$_FILES['name'][0]
$_FILES['name'][1]
...
$_FILES['type'][0]
$_FILES['type'][1]
...
$_FILES['error'][0]
$_FILES['error'][1]
...
$_FILES['tmp_name'][0]
$_FILES['tmp_name'][1]
...

$_FILES['size'][0]
$_FILES['size'][1]
...



Wygodniej ją przetwarzać, jeśli klucze byłyby zamienione miejscami, tzn. [0]['name'], itd.
Oto funkcja, która zamienia te klucze miejscami w tablicy 2-wymiarowej:
function replaceKeys(array $arr){
    $newArr = array();
    foreach($f as $k1 => $v1){
        foreach($v1 as $k2 => $v2){
             $newArr [$k2][$k1] = $f[$k1][$k2];
        }
    }
    return $newArr;
}

Teraz jest wygodniej sprawdzać uploadowane pliki:

$files = replaceKeys($_FILES);
foreach($files as $file){
    if($file['error'] == 0){
        // ......
    }
}

środa, 14 grudnia 2011

Tablica znaków w PHP bez używania pętli

Cześć,
pokażę, jak stworzyć tablicę znaków w PHP nie używając pętli, czyli
array('A', 'B', ..., 'Z', 'a', 'b', ..., 'z').

// utworzenie tablicy liczb array(65, ..., 90)
$big = range(65, 90);
// utworzenie tablicy liczb array(97, ..., 122)
$small = range(97, 122);
// złączenie tych tablic
$nums = array_merge($big, $small);
// stosujemy funkcję chr() do każdego elementu tablicy
$letters = array_map('chr', $nums);
var_dump($letters);

Liczby w tablicach $big i $small to kody ASCII liter.

Jeżeli chcemy otrzymać string 'ABC...Zabc....z',
to wystarczy złączyć elementy tablicy:
implode('', $letters);

niedziela, 4 grudnia 2011

Znak wodny na wszystkich obrazkach w katalogu

Cześć,
pokażę, jak dodać do zdjęć znak wodny, nie modyfikując i bez żadnych przeróbek wcześniejszego kodu.
Zakładamy, że zdjęcia znajdują się na serwerze w katalogu images.
Do tego katalogu wrzucamy obrazek ze znakiem wodnym najlepiej w formacie PNG, aby mieć wpływ na przeźroczystość. Niech się nazywa watermark.png.

wtorek, 21 czerwca 2011

Jak korzystać z innego configu pagincaji w KO3

Załóżmy, że w pliku config/pagination.php mamy:

<?php defined('SYSPATH') or die('No direct script access.');
return array(
  'default' => array(
    'current_page'      => array('source' => 'route', 'key' => 'id'),
    'total_items'       => 0,
    'items_per_page'    => 10,
    'view'              => 'pagination/floating',
    'auto_hide'         => true,
    'first_page_in_url' => false,
  ),
  'other' => array(
    'current_page'      => array('source' => 'route', 'key' => 'id'),
    'total_items'       => 0,
    'items_per_page'    => 50,
    'view'              => 'pagination/basic',
    'auto_hide'         => false,
    'first_page_in_url' => true,
  ),
);


Zwykle korzystamy z ustawienia 'default':

$gallery_pagination = Pagination::factory(array(
            'total_items' => $gallery->countAll(),
            ));
           

Jeśli chcemy skorzystać z innych ustawień, nie wpisując wszystkich ustawień za każdym razem, gdy tworzymy paginację, możemy przekazać w tablicy w metodzie factory indeks 'group'. Oczywiście można użyć innych opcji, które nadpiszą te z configu:

$gallery_pagination = Pagination::factory(array(
            'group' => 'other',
            'total_items' => $gallery->countAll(),
            ));


Można sprawdzić, co się wyświetli:

echo $gallery_pagination->render();


wtorek, 24 maja 2011

Obsługa błędu 404 w Kohana 3.0 - plik bootstrap.php


Kod należy umieścić w pliku bootstrap.php:
    $request = Request::instance();
    try {
         $request->execute();
    } catch (Exception $e) {
        Kohana::$log->add(Kohana::ERROR, Kohana::exception_text($e));
      
        if(Kohana::$environment == Kohana::PRODUCTION){
            $request->status = 404;
            $request->response = View::factory('error/404');
        }
        else{
            throw $e;
        }      
    }

    $request->send_headers();
    echo $request->response;

Oczywiście, dla tego przypadku należy dodać plik 404.php w katalogu views/error.

W zależności od ustawienia

Kohana::$environment = Kohana::DEVELOPMENT;
lub
Kohana::$environment = Kohana::PRODUCTION;

wyświetlana jest strona błędu Kohany lub widok z pliku 404.php


wtorek, 8 lutego 2011

Renderowanie obrazków w Kohana 3

Aby pokazać obrazek w locie (np. miniaturka, ze znakiem wodnym), w PHP tworzymy obrazek, podajemy typ mime oraz wysyłamy do przeglądarki:
header('Content-type: image/jpeg');
$img = imagecreatefromjpeg('plik.jpeg');
imagejpeg($img);
imagedestroy($img);

W Kohana wygląda to tak:
W kontrolerze np. obrazek.php dodajemy akcję action_render(). Podobnie, jak w czystym PHP, musimy utworzyć obrazek z pliku, podać typ wysyłanych danych, wysłać je w nagłówkach oraz zwrócić wyrenderowany obrazek:
<?php defined('SYSPATH') or die('No direct script access.');

class Controller_Obrazek extends Controller {
        public function action_render(){
            $this->request->headers['Content-type']='image/jpeg';
            $this->request->send_headers();
            $img=Image::factory('media/images/obraz.jpg');
            $this->request->response=$img->render('jpg');
           
        }
}

Wywołujemy następująco:
<?php echo Html::image('obrazek/render'); ?>

W ten sposób można również ukryć ścieżkę do zdjęć.
Oczywiście można przekazać do akcji dowolny obrazek:
<?php echo Html::image('obrazek/render/' . $nazwa_pliku); ?>

<?php defined('SYSPATH') or die('No direct script access.');

class Controller_Obrazek extends Controller {
        public function action_render(){
            $nazwa_pliku=$this->request->param('id'); //zależnie od ustawień w bootstrap.php
            $this->request->headers['Content-type']='image/jpeg';
            $this->request->send_headers();
            $img=Image::factory('upload/' . $nazwa_pliku);
            $this->request->response=$img->render('jpg');
        }
}



poniedziałek, 7 lutego 2011

Swift Mailer jako moduł w Kohana 3

Krótki tutorial na temat integracji Swift Mailer jako modułu Kohana 3.
Najpierw należy utworzyć katalogi i pliki:
/modules/swiftmailer
/modules/swiftmailer/init.php
/modules/swiftmailer/classes

Skopiuj do katalogu /modules/swiftmailer/classes/  najnowszą wersję Swift Mailer.
W pliku /modules/swiftmailer/init.php umieść następującą linię:
<?php
require Kohana::find_file('classes', 'Swift-4.0.6/lib/swift_required');

Następnie do pliku bootstrap.php dołącz moduł:
'swiftmailer'  => MODPATH.'swiftmailer',


Teraz wystarczy utworzyć obiekty Swift_Message, Swift_SmtpTransport, Swift_Mailer oraz podać dane połączenia, 

$message=new Swift_Message();
$message->setSubject('Temat');
$message->setFrom(array('od_email@od_email.pl'=>'Admin'));
$message->setTo(array('do_email@ do_email.pl'));
$message->setBody('Treść');

$transport=new Swift_SmtpTransport();
$transport->setHost('host');
$transport->setUsername('user');
$transport->setPassword('password');

$mailer=new Swift_Mailer($transport);

$result=$mailer->send($message);


piątek, 21 stycznia 2011

Kohana 3 - spolszczenie

Dziś pokażę, jak wyświetlać polskie komunikaty.
Na początku edytujemy plik bootstrap.php. Należy dodać nową linijkę:
I18n::lang('pl');

Można ją dopisać zaraz po autoładowaniu klas:
spl_autoload_register(array('Kohana', 'auto_load'));

Następnie zamienić te linijki:
date_default_timezone_set('America/Chicago');
setlocale(LC_ALL, 'en_US.utf-8');

na:
date_default_timezone_set('Europe/Warsaw');
setlocale(LC_ALL, 'pl_PL.utf-8');

Następnie tworzymy plik /application/i18n/pl.php z zawartością:
<?php defined('SYSPATH') or die('No direct script access.');

return array
(
     'Polish' => 'Polski',
     'Hello, world!' => 'Witaj świecie!',
     'First' => 'Pierwsza',
     'Last' => 'Ostatnia',
     'Previous' => 'Poprzednia',
     'Next' => 'Następna',
);

Teraz, wyświetlając paginację mamy polskie wyrazy zamiast angielskich.
Działa to tak:
w odpowiednich plikach (np. w widoku paginacji /module/pagination/views/pagination/basic.php) widać polecenia typ:
<?php echo __('First') ?>
<?php echo __('Previous') ?>
<?php echo __('Next') ?>
<?php echo __('Last') ?>

Dzięki funkcji __ (2 podkreślniki) Kohana wie, że ma korzystać z plików w katalogu i18n i zamieniać je zgodnie z wzorcami.
Mam nadzieję, że wszystko jest zrozumiałe.

czwartek, 13 stycznia 2011

Wiele paginacji w Kohana 3

Pokażę, jak korzystać z kilku paginacji w Kohna.
Załóżmy, że mamy stronę foto galerii, na której są miniatury, a pod nimi komentarze.
Chcemy, aby przewijanie stron z miniaturami i przewijanie stron z komentarzami było niezależne, np. przeglądamy piątą stronę ze zdjęciami i dziesiątą z komentarzami i nie chcemy, aby przejście do kolejnej strony z komentarzami spowodowało przejście do pierwszej strony ze zdjęciami.