Kedves Blogolvasók!
Milyen témákra van igény?
- More code dump?
- More psycho?
- More energy?
- More passion?
Jöhet privben is, kamu email címről is.
Thx
The Überblog Management Team
Jelöld be, hogy főbb mely kategóriákat akarod olvasni, vagy ha csak egyet: kattints a nevére.
Kedves Blogolvasók!
Milyen témákra van igény?
Jöhet privben is, kamu email címről is.
Thx
The Überblog Management Team
8.3.7-es PHP-n hasítunk a bloggal
OMG it's fantastic. Big thx for United Technology Alliance!
PHPStan lokálban, CI-on
Jelenleg így futtatok CI-on egy PHPStant level=5-tel, és 7-tel is. Az 5-öt zölden tartom, a 7-ből néha okulok valamit.
Fut egy PHPUnit is amibe nem rég migráltam be a saját fw-ben írt tesztjeimet (elég könnyű volt mert kb leutánoztam a PHPUnit alapabb dolgait).
Fut egy Playwright is.
Valamint egy saját stringcounter találmány, ami különböző statisztikákat készít a blog forráskódjában előforduló egynémely fontosabb szavakról.
Fut egy dependabot is.
Lokálban pedig precommitra bekötöttem eddig 3 dolgot, azt majd egy külön bejegyzésben.
name: PHPStan Analysis Level=5 should be green
on:
push:
branches: ["**"]
paths:
- '.github/workflows/phpstan-lvl-5.yml'
- 'phpstan.neon'
- 'phpstan-baseline.neon'
- 'liveroot/composer.**'
- '**.php'
pull_request:
branches: [ main, master ]
permissions:
contents: write
jobs:
build:
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup PHP with tools
uses: shivammathur/setup-php@v2
with:
php-version: '7.2.32'
tools: composer, phpstan
- name: Composer install
run: |
cd liveroot
pwd
ls
composer install
- name: PHPStan Analysis level 5 - keep it green
run: |
pwd
cd liveroot
pwd
ls
phpstan analyse . -c phpstan.neon --level=5 --memory-limit 1024
A Linkbár checkerben áttértem GuzzleHttp-re, de miket lehetne még ellenőrizni?
Ezek mondjuk mind elég bonyik, mármint a lekezelésük, hogy na akkor mi legyen. A lejárt linkeket általában manuálisan szoktam deprekálni a bejegyzésekben egy olyan két hónapja. Természetesen írni akarok erre egy automatizmust.
Hát ennek már ideje volt, végre lehet profilképet feltölteni automatizáltan.
Meg a postokhoz is (szerkesztőként nyilván).
Még sok fejlesztenivaló maradt a témában...
Még az is lehet hogy nextjs-ezni fogok? Meg lettem említve egy ilyen meló kapcsán.
Hogy könnyebb legyen az élet.
I'm LOVIN it!
ápr. 25. 03:24 Annyira nem is kicsi most mar, tud ec2 deployt, meg mindenfelet.
A parancsok logolásához Monolog-ot használok, a Monolog parse-olásához pedig devdot/monolog-parser-t.
máj. 08. 14:19 ezt jól használhatom precommit hookként is!
Legújabb dependenciánk.
Képfeltöltés, képátméretezés, szöveg/logó elhelyezése, ratio megtartása, crop, stb.
Különböző szövegmezők formázásai a blogon.
<?php
namespace Uberblog\Text;
use Uberblog\System\DI;
class PreSaveFormatterChains
{
public function formatPreSaveUserTextarea(string $text,
string $inputType): string
{
return $this->apply($text, $inputType,
DI::MarkDownPresaveFormatter(),
DI::BbcodePreSaveFormatter(),
DI::TextPreSaveFormatter(),
DI::CommentPreSaveFormatter()
);
}
private function apply(string $string,
string $inputType,
PresaveFormatterInterface ...$formatters): string
{
foreach ($formatters as $formatter) {
$string = $formatter->doThePresaveFormatting($string, $inputType);
}
return $string;
}
public function formatPreSaveEditableTextarea(string $text,
string $inputType): string
{
return $this->apply($text, $inputType,
DI::PostPreSaveFormatter(),
DI::TextPreSaveFormatter()
);
}
public function formatPreSaveGeneratedTextarea(string $text,
string $inputType): string
{
return $this->apply($text, $inputType,
DI::PostPreSaveFormatter(),
DI::MarkDownPresaveFormatter(),
DI::TextPreSaveFormatter()
);
}
public function formatPreSavePostTitle(string $text,
string $inputType): string
{
return $this->apply($text, $inputType,
DI::PostPreSaveTitleFormatter()
);
}
}
Like? Dislike? Ötlet? Javaslat?
(7.2-es PHP-re be vagyok korlátozva, másképp mondjuk minimum enumok lennének az $inputType-ok, most máson nem gondolkodtam, hogy mi lenne frissebb PHP-vel.)
21:09 elvileg hamarosan lesz 8.2-es PHP-nk, yeaaah
Lehet kommentálni Markdownban és BBcode-ban is. Vegyíteni is lehet.
FormatterChainConcept in da house.
Értelemszerűen nem sorról sorra de van ezekben pár sor ami érdekes számomra. Az AWS könyvből főképp az ECS/EC2 pl. Bár kicsit más jellegű írás, mint amit kerestem (nagyon high level). Mindegy, kezdetnek egynek nem rossz.
Mivel az utóbbi időben 1-2 code sample-t is tettem az oldalra, syntax highlighthoz berántottam a prism js-t.
Közben lehet, hogy a Torchlight jobb lenne syntax highlightra, de első körben nem láttam plain php támogatást.
Amúgy én Parsedownt használok .md parsingra (ami elvileg a leggyorsabb markdown parser). The struggle is real. Mondjuk a prism se rossz, de ha lehet elkerülném a kliens oldali js bütykölést, performance okokból.
Hát ez ugye semmi extra, aki használ bármilyen épkézláb autoloadert (pl a Composert), az tudja hogy mi az elnevezési konvenció. \Namespace\Subnamespaces\Classname, és a Classname megfeleltethető egy .php fájlnak ugyanezen a néven. Case sensitive (miután a fájlrendszer amire mappelődik a namespace, többnyire case sensitive az adott OS-en). Ennyike.
Na ez már combosabb, nem volt türelmem/időm normálisan végigolvasni, kigyűjtöttem belőle pár core gondolatot/buzzwordöt.
Upload an avatar: <input type="file" name="my-form[details][avatars][]" />
Elérése PHP-ből:
$request->getUploadedFiles()['my-form']['details']['avatars'][1];
Ahol az 1 egy többfájlos feltöltés esetén az 1-es indexű (0-tól kezdődő) feltöltött fájlt jelenti.
Másik példa:
$file0 = $request->getUploadedFiles()['files'][0];
$file1 = $request->getUploadedFiles()['files'][1];
printf(
"Received the files %s and %s",
$file0->getClientFilename(),
$file1->getClientFilename()
);
// "Received the files file0.txt and file1.html"
move_uploaded_file() helyett érdemes a moveTo($targetPath)-t használni.
MessageInterface: immutable, "módosító" függvények új példányt adnak vissza belőle. RequestInterface és ResponseInterface szülője.
nekem egyértelműen úgy tűnik, hogy erre kivételesen érdemes egy libraryt berántani, nem magamnak leimplementálni. A blogon egyébként van egy Request classom ami sztem ügyes meg szép, de köze nincs ahhoz amit ez csinál. Lehet hogy ez egy réteg lehetne alatta, maybe. Nem tudom eldönteni. Response-t nem csináltam, de igény az volna rá.
Btw egy rakás PSR-7 implementáció van, ld. packagist.org
Guzzlehttp/psr7-nek 700 millió letöltése van a packagist-en. "Packagist is the main Composer repository". A laminas a zend-framework utódja. Abban írt anno Fater valamit egy ügyféljelöltünknek, akiből végül cégátszervezés miatt nem lett ügyfél.
"Common interface for dependency injection containers"
public methods:
public function get(string $className);
public function has(string $className);
A $className-et a PSR $id-ként említi, de szvsz nyilvánvalóan ClassName-ről van szó. (Right?)
"Users SHOULD NOT pass a container into an object so that the object can retrieve its own dependencies. This means the container is used as a Service Locator which is a pattern that is generally discouraged."
Ezen az egészen el lehet vitatkozni, lesz egy írásom majd a PHP-DI-ról, vagy ki tudja, lehet hogy már megjelenik mire ez megjelenik :Đ
Előkövetelmények (Windowson)
curl -s https://laravel.build/example-app | bash
cd example-app
./vendor/bin/sail up
Esetleg
./vendor/bin/sail up -d
Hogy csöndben legyen, meg hogy ne pazaroljunk el rá egy külön nyitva tartandó ablakot.
Nekem most momentán azért kell egy projekthez, mert fel akartam rakni a PHPStant, és a natív Windowsos PHP-mmel valahogy akadt, és úgy gondoltam, hogy nem arra fordítom az energiámat, hogy a Windowsos PHP problémámat próbálom megoldani, hanem inkább felteszem a Sailt, mert abban úgyis van egy csomó dolog amire szükségem lenne egyébként is.
Amíg ezt leírtam, a Sail nagyjából fel is rakta magát.
Alapból egy nagyon kellemes hibaoldallal fogad, mert még nem futtattuk a migrációt.
Segítsünk ezen, futtassunk egy migrációt:
./vendor/bin/sail artisan migrate
A sailhez majd vagy fel kell venni egy aliast, vagy csinálni rá egy symlinket.
Mindenesetre fáradozásunk eredménye egy gyönyörű üres Laravel oldal a localhoston.
Pár blog-todo:
Lesz egy PSR sorozatom (), egyelőre a köv PSR-ekkel
Előre bocsájtom hogy nem ezekkel kelek és fekszem.
Van egy endpointom a blogon, amin a TODO itemeket csekkolgatom ki-be (/my/todo/toggle/{id}). Ez nem Laravelben van, hanem a jó öreg saját blogengine-ben, és most a laraveles felületre nem akarok semmi JS-t tenni. Az endpoint egy JSON-t ad vissza:
{ "checked": true }
vagy
{ "checked": false }
Annak függvényében nyilván hogy a TODO done lett-e vagy .. todo.
Igazából sosem használtam a Guzzle-t. Nem nagyon akarok sokmindent változtatni, annyit akarok, hogy az endpointomat meg tudjam hívni, amihez szükségem van arra, hogy bejelentkezett adminnak lásson a blog. Ehhez át kell küldenem a vid, uid, sid cookie-kat.
A Guzzle http kliensét akartam kipróbálni, ez a lényege a feladatomnak.
Következőt sikerült produkálni, ez egy Laravel kontrollerben van:
namespace App\Http\Controllers\Admin;
use GuzzleHttp\Client;
class TodoController
{
public function toggle(HbTodo $todo)
{
$headers = [
'Cookie' =>
'vid=' . DI::Cookies()->getVid()
. ';uid=' . DI::Cookies()->getUid()
. ';sid=' . DI::Cookies()->getSid()
];
$client = new Client();
$res = $client->post(DI::Config()->siteUrl
. '/my/todo/toggle/' . $todo->t_id, [
'headers' => $headers
]);
$contents = json_decode($res->getBody()->getContents());
return redirect()->route('admin.todos', [
'checked' => $contents->checked
]);
}
A fenti kódban a DI nevű class egy saját dependency injection megoldás (használhatnám a PHP-DI-t pl, de minek, ugye, itt minden saját). (Egyik nap ami azt illeti be is rántottam a PHP-DI-t a blog alá, aztán kitöröltem. Teljesen működőképes volt stb, de ... akartam írni egy postot a PHP-DI-ról hogy miért nem azt használom... majd egyszer talán. Közben létrehoztam a postot hogy nyomasszon, benne van a queue-ban, mire megjelenik, szeretnék írni bele valamit. :Đ )
Na de a lényeg: létrehozzuk a Guzzle Client-et, simán küldünk vele egy POST requestet, belesütjük a Cookiekat, json_decode-oljuk a választ az endpointról, és átirányítjuk a usert (magamat) az új Laraveles TODO admin oldalra, becsűrve az URL-be hogy done lett-e az item vagy todo (checked=0 v checked=1).
A Guzzle ->post() helyett tudna ->postAsync() -et is, az elég fontos funkció lenne, de akkor nem kapnám meg, hogy mi lett az endpoint válasza, és így nem tudnám belesütni az URL-be.
Amúgy az URL-be belesütés nyilván nem annyira hatékony módja a kommunikációnak, de leszarom, egyszerűen csak ismerkedek libekkel.
Van amikor hasznos, pl. egy sima URL logból látom, hogy mondjuk valaki hozzászólt egy topikhoz, mert az URL-ben benne van hogy &thx4=cmnt (aki nézi az URL-t, biztos találkozott már ilyennel a blogon, miután hozzászólt valami témához). Kiszedhetném belőle, a blogon van egy kellemes kis értesítős megoldás (most már azzal is találkozhattok pl. ha beléptek vagy kiléptek, vagy módosítjátok a profilotokat).
Éleslátók észrevehetik, hogy a Laravel tök faszán URL-ből felpéldányosít nekem egy HbTodo objektumot. Ez szerintem kurvajó. Itt a példában tök fölösleges, mert csak az ID-jára van szükségem. De annyiból mégis jó, hogy ha rossz ID lenne, akkor már eleve a Controller végrehajtása előtt kapna a user egy HTTP 404 not found hibát. Így az ID-t nem kell manuálisan validálni, hogy létezik-e. Szóval annyira mégse fölösleges. Good.
Mert perpill a Laravel dolgaira akarok fókuszálni, épp egy backend developer role-ra pályázok, és nem akarok JS-sel foglalkozni most, így is végeláthatatlan dolognak kell utánanézzek. Egyébként természetesen JS-ben lenne logikus, pláne ha már ilyen nice endpointom van ami JSON-t ad vissza.
Másfelől perpill nem tenném le a voksomat semmilyen JS lib mellett, a Reactot évente újra kell írni (nekem nem lesz ennyi kapacitásom a blogra, most épp van, de tudom hogy nem lesz), jQuery-t minek gyakoroljak 2024-ben, stb.
Legfőképp meg azért mert a Laravel admin felületemre egyelőre semmi JS nincs bevezetve. Pedig fájóan kéne egyébként. Fel is jegyzem:
Dependabot berakva a blog alá, frissített is 1-2 cuccot, volt amin meglepődtem
(kicsit régi volt)
Nice.
Blade template-ben így lehet használni, ha a meződ alapból nem lenne Carbon [ld lejjebb]:
<div>
{{\Carbon\Carbon::parse($todo->t_inserted_at)
->diffForHumans()}}
</div>
Vagy így is:
@inject('carbon', 'Carbon\Carbon')
<div>
{{$carbon::parse($todo->t_inserted_at)->diffForHumans()}}
</div>
Amit megjelenít (pl):
1 day ago
Vagy magyarul:
{{$carbon->parse($todo->t_inserted_at)
->locale('hu_HU')->diffForHumans()}}
A kimenet:
1 napja
A locale('hu_HU') nem szükséges, ha a config/app.php-ben be van állítva, hogy
'timezone' => 'Europe/Budapest',
És akkor említettem hogy "ha a meződ nem lenne alapból Carbon". A Laravel ugye egy inserted_at és egy created_at mezőt használ a db-ben a rekord beszúrási/frissítési időpontjaira. Ezeket a mezőket a Laravel alapból castolja Carbon példányokra, így alapból hívható rajtuk a diffForHumans metódus, illetve amúgy bootolhatod úgy is az appot hogy bizonyos mezőket alapból castoljon Carbonra.
Személy szerint nem ezeket a mezőneveket használom a DB-ben a blogon, de a Laravel modelljeit lehet instruálni, hogy más mezőneveket használjon, így azokat is Carbonná konvertálja by default, megkönnyítve a template-ben a dolgunkat, nem kell a Carbont külön injektálni. A Laravel setupolása igazából eredetileg nem volt a célom ebben a postban, úgyhogy nem is megyek bele jobban. :)
Az a gyanúm, hogy frissebb Laravelekben lehetne csinálni egy ilyet, de a blog momentán 7.2-es php-n fut (ami 7-es laravelt jelent), úgyhogy itt ezt nem tudom kipróbálni. Az AppServiceProvider.php-ben van egy boot metódus:
public function boot()
{
// ...
Blade::stringable(function (Carbon $date) {
return $date->diffForHumans();
});
}
Ezzel elvileg az összes dátumot így lehetne kiíratni. Idő hiányában ezt most nem tudom kipróbálni 11-es laravel projektben, mert mozdulnom kell a köv témára. :) Next time maybe.
Nyilván egy csomó dolgot tud még, szóval ld. fenti link, vagy nesbot/carbon on packagist, vagy laravel.com doksi.
Valami kurvalassú benne de most már lehet (nekem) a bejegyzésekben a checkboxokat UI-ról kipipálni és megjegyzi veeheheh. Kibaszott egy monstrum megoldás, mert amellett h felveszi DB-be, átírja a szerkeszthető szövegmezőt is (ami nemrég került bevezetésre), meg a legenerált köztes HTML mezőt is. Gyakorlatilag újragenerálja a bejegyzést. Mivel ez nem lesz egy túl gyakori művelet így 0.1-nek bőven megteszi. Szerintem ez lesz az első feature amitől megválok a jövőben, nem nevezném elegánsnak.
Ehun egy-két példa:
ápr. 08. 19:45 sose válok meg tőle, imádom, eddig kb. 100 létrehozott todonál tartok ![]()
$ ./sail composer require laravel/breeze --dev
(Ja a ./vendor/bin/sail -re van egy symlink.)
(Ezt a parancsot így wsl-ben kell kiadni ha épp Windowson vagyunk.)
Milyen csomagjaink vannak most?
| Csomi | Miez |
|---|---|
| User reg, login, pwchange, pw confirm, pwreset, simple profile page + opcionálisan Livewire, Inertia + opcionálisan Vue/React. Pretty much out of box if you ask me. | |
| A Laravel saját Docker wrappere, felhúz neked egy PHP containert, MySQL containert, Redis containert, látok itt még valami test, mailpit és selenium konténereket. Aham a mailpitet eléred a 8025-ös porton, ahol ül egy lokál inbox a rendszerből kiküldött emailekkel (standard thing) | |
| "authentication system for SPAs (single page applications), mobile applications, and simple, token based APIs" | |
| A Laravel REPL-je | |
| DateTime, bővebben egy hamarosan megjelenő bejegyzésben | |
| "beautiful error reporting" | |
| it's like Tailwind CSS, but for the PHP command-line applications | |
| "beautiful error page for Laravel apps" - hozzáteszem tényleg kurvajól néz ki, ez volt az első dolog amivel találkoztam a Laravel felrakása után (írási jogosultság-para miatt), szép, true. |
Aham, a feléről nemtom micsoda, a Breeze-t most ismertetem, a Sail egy Docker-compose wrapper a Laraveltől, a Tinker öö passz, a Carbon ha az amire gondolok akkor valami időkezelés, Collision az valami hibakezelő cucc commandline-ban, Termwind passz, Ignition mintha az is valami hibakezelés lenne. ápr. 07. 19:35, közben utánanéztem a dolgoknak, be is írtam a táblázatba
Laravel Breeze is a minimal, simple implementation of all of Laravel's authentication features, including login, registration, password reset, email verification, and password confirmation. In addition, Breeze includes a simple "profile" page where the user may update their name, email address, and password.
Okés.
Laravel Breeze's default view layer is made up of simple Blade templates styled with Tailwind CSS. Additionally, Breeze provides scaffolding options based on Livewire or Inertia, with the choice of using Vue or React for the Inertia-based scaffolding.
Értem.
Igazából Nekem egy loginra (screenre) volt szükségem, mert eggyel korábban, amikor még aludtatok, a
$ ./sail artisan install:api
eredményeképp azt kaptam, hogy
Route [login] not defined.
Szóval gondoltam mi lenne ha kivételesen ezt nem írnám meg magamnak manuálban, hanem megnézném, hogy mit ad a Laravel. Hát itt tartunk. Azaz már nem egészen itt, mert a composer require laravel/breeze után ez volt a javasolt köv lépés:
$ ./sail artisan breeze:install
Itt felajánlott amolyan ASCII UI-on egy pár választási lehetőséget, én a következő szavazatokat adtam le:
| Kérdés | Válasz |
|---|---|
| Which Breeze stack would you like to install? | React with Inertia Az inertiáról egyelőre nem tudom hogy micsoda, de a React az azért jó, mert a csőben levő ügyfelünk Reactozik. |
| Would you like any optional features? | Dark mode & TypeScript Ezeknek meg Pas fog örülni |
| Which testing framework do you prefer? | Pest Itt fel volt kínálva a PHPUnit is de azt ismerjük és véletlen túl hatékonyak lennénk benne. |
Bennem most felmerult h esetleg ujrairhatnank a site-ot (cchu) ebben
...
Aztán belenéztem a cchu-ba hogy milyen feature-ök vannak benne, hát good luck hogy ezt szó szerint újraírja valaki. Nyilván mást lehet írni helyette. De elég.. brutál dolgokat tud. Nem is értem, hogy a francban volt erre energiám anno. (nem a publikus felületre gondolok annyira hanem a 'members area'-ra.)
Lehet h tenyleg autista vagyok? Mindenhez redirectet irok, most ez az uj Thing.
Kurvajol rendet raktam a kategoriak kozott, legalabbis jobb lett, mint volt. Thx 2 Laravel Category Admin UI.
A mai fejlesztest kifejezetten elveztem, ujra.
Viszont nem foglalkoztam az Amazon cuccokkal
Ma masodik kor a potencialis uj ugyfelnel... Q elet.
Viszont Markdown power ![]()
Raktam be a blog alá laravelt jól. Egyelőre - és várhatóan a jövőben is - kizárólag admin funkciókhoz. Nem rossz az ha 20 év múlva is megy valami. ![]()
Vicces, 2 hónapja még minden dependenciámat ki akartam vakarni a blog alól, most meg épp abban vagyok h berántsak ezt-azt.
Szerintem ezt a site-ot amúgy úgy érdemes csinálni - és nagyjából így is van -, hogy a "mainstream" oldalhoz nem nagyon használok külső dolgokat, az adminisztrációhoz, fejlesztéshez, meg igen.
Mert előfordulnak röpke 10 évek az életemben amikor mondjuk nem annyira foglalkozom a bloggal, és utána kb lehetetlen a régi dependenciákkal mit kezdeni, meg ugye nem is szereti az ember annyira a lejárt dolgokat, de nehéz upgrade-elni, kivakarni, stb. Ez nem egy 200 fős projekt, érted. Nincs folyamatosan up-to-date tartva. Tökjó ha olyan dolgokból épül, ami menni fog az unokáimnak is.
Most idén amikor elkezdtem foglalkozni vele újból, konkrétan taskokat hoztam létre arra, hogy pár dependenciától nézzem már meg hogy miként tudnék megszabadulni. Hát sejthető hogy mennyire sikerült. (Semennyire.)
Ugyanakkor ami mondjuk csak lokál fejlesztéshez volt használva - vagrant - azt nyilván 0 sec alatt kivágtam.
Mondjuk most már kezdek úgy behúzni ezt-azt hogy kb feature switchelhető hogy van-e vagy nincs, azt' max nincs használva az adott funkcionalitás. Dehát ezt nyilván nem lehet mindennel megcsinálni.
Voltak itt Meliek. Elmentek. Altalaban nem erzem magam olyan egyedul, mint most. Csak most eros a kontraszt.
Konkretan ram tort a panik.
Idokozben vege lett.
Beszeltem anyammal ahol a "true self"-em elojohet. Elegge elveztem, alig tudtam abahagyni, vegul azert ejjel 2.30kor lekorlatoztam magam.
Ezeket at kell nezzem a keddi interjuig
Es tok jo lenne ha el tudnek . De lathatoan nehezen menedzselem a prios dolgokat. Anyam tanacsa: mi hataridos. Nos egyedul a keddi meeting hataridos, a tobbi a kutyat nem erdekli (magamon kivul) hogy elkeszul-e v mikor
Meliek behuztak a , lol
De a true selfet egyebkent szivesen megmutatnam masoknak is, de valszeg korlatozottabb lenne ra az erdeklodes.
, ami valszeg senkit se erdekel egyebkent, de engem annal inkabb
Áttértünk Amazon RDS-re, ami a DB-t illeti.
Ultra happy.
Felraktam a Laravelt, kapásból egy hibaüzenettel indított, de kurvára tetszett hogy hogy néz ki. Regisztráltam magam a -on is, itt lehet szervert bérelni 12 USD/hótól.
Ma derült ki számomra hogy az új ügyfelünk már múlt héten visszajelzett hogy lesz meeting, de csak Past címezték be... én meg teljesen magam alatt voltam, hogy még csak válaszolni se válaszoltak...
Elég bugos volt a kereső. Most már kevésbé bugos. (Nem tökéletes, de itt ez a keret van.
)
Blog health check & maintenance.
(A második kép valójában nem kattintható de már a fülemen jön ki a CSS hegesztés, sry.)
Még gondolkodom rajta hogy automatizáljam-e az ilyen orphanok törlését. Bizonyos esetekben mehet, de mondjuk találtam értékes adatokat is a múltból amiket restauráltam. (Pl. egy rakás kommentet egy törölt bejegyzéshez.)
Oké sikeresen áttértünk utf8mb4-re. Ofkorsz élesen kellett kipróbálni. Ofkorsz elhasalt a felénél.
De most már lehet smiley-kat írni a szövegbe. Mármint igazi smiley karaktereket. Mind blown.
Erre azért volt szükség mert kimásoltam ide egy chatrészletet és elveszett a bejegyzésem smiley-tól hátralevő része. Elsőre nem vágtam hogy mi van.
A dolog mindenesetre elég könnyen ment. Nem is vártam mást, annak ellenére hogy egy encoding váltás anno micsoda KŐKEMÉNY SZOPÁS volt.
Hogy b*nád meg phpstorm, besz.pattál a refaktorral.
Hát a f.szom, nem mindent nevezett át.
11:45 resolved.
Uralkodik.
Baszki kikapcsolt a gepem, a legizgalmasabb resznel. Visszakapcsolom.
23:09
Végre zöld a phpstan, el se hiszem, persze új baseline fájllal nyilván csak zöld lehet, ez némileg levon belőle.
A mai nap kiemelt kommitja: render templates with reflection. Yeah.
Feb 6 óta 21%-kal kisebb lett a phpstan-baseline.neon fájl, ami a(z amúgy 7-es levelre állított) phpstan baseline
fájlja.
(Mi az a baseline? Ez sorolja a projektben található hmm szabálysértéseket/hinteket.)
Good.
Miután kidühöngtem magam a Rectorral kapcsolatban, folytatom a konfigurálását... ![]()
Long term remélhetőleg megéri belőni olyanra, amilyenre szeretném.
Muszáj vagyok tovább menni az automata refaktorálás "csapdáin".
Valamiért a PHPStorm is nagyon kínálgatja hogy egy függvényből való visszatérés előtt az utolsó változót inline-oljam, és a Rector is simán automatán kiirtja a fölöslegesnek vélt utolsó változókat return előtt, tehát:
$x = something(..);
return $x;
Helyett használjam ezt:
return something(...);
De vaffankúló (amúgy ezt nem szoktam használni, de ide illik), komolyan, miért?! Mi ez a trend? Rájöttünk ezer éve, hogy a függvénynevek és változónevek ugye milyen fontosak hogy jól legyenek elnevezve, erre jön valaki (egy egész trend), és azt mondja, hogy szerinte spóroljunk meg egy változónevet.
Ami azt jelenti, hogy elveszítesz egy tök fontos információt, hogy mi történt az utolsó lépésben.
Csak a példa kedvéért:
function foo($pattern) {
// ... some other logic here ...
return preg_replace('{^(([^.+*?\[^\]$(){}=!<>|:\\\\#-]+|\\\\[.+*?\[^\]$(){}=!<>|:#-])*).*}', '$1', $pattern);
}
A fenti kódot a Composer Autoloaderéből szedtem, szóval teljesen real world, és biztosan nem a saját hülyeségem (ott fel van kommentezve* amúgy, és nem ennyiből áll a függvény, de ettől még tök jó példa). Tegye fel a kezét, aki szerint tök fasza, ha nincs elnevezve, hogy mit is kapunk ebből a preg_replace-ből. :Đ
* arról nem is beszéltem h van aki szerint a kommentek is hülyeségek :D Egy időben amúgy totál ezt vallottam én is, most szopok rendesen ahogy refaktorálom a blogot :D Kommentezek "mindent". (És nem azért mert nem használtam jó változóneveket/függvényneveket.)
Most hogy csak egy példát mondjak a Rectorból, de eddig amúgy 6 konkrét rule-t tiltottam le belőle és 2 setet egyszerűen használhatatlannak ítéltem (a DEAD_CODE-ot és a CODE_QUALITY-t)
Legyen két példa:
settype($x["hello"], "string");
Szerinte lecserélhető erre (le is cseréli szorgalmasan):
$x["hello"] = (string)$x["hello"];
Ez tökjó de ugye undefined index error kapásból ha az adott index nem létezik, és azért idegesít ez engem, mert sztem tök nyilvánvaló, szóval nem értem hogy hogy hozhatnak létre ilyen rule-t.
Másik:
Szerinte lecserélhető arra hogy
Ezt bőszen meg is teszi. Oké. És mi van azokkal a függvényhívásokkal, amik átadják ezt a változót? Azokhoz nem nyúl hozzá. ¯_ (ツ) _ / ¯ Gyanítom akkor se, ha mondjuk nem az utolsó hanem egy közbülső unused variable-t töröl ki a függvény szignatúrájából. Ami ugye nyilvánvalóan konkrét bugot eredményez, hiszen elcsúszik a paraméterátadás.
Igazából végül annyi ilyen szart kellett letiltanom hogy nem maradt javaslata a kódra nézve
Eh. Na majd futok vele talán még köröket.
$date = date("Y-m-d", $timestamp) // it works perfectly
install phpstan
Na ha már törünk mindent, akkor legyenek end-to-end / UI tesztek. Az utóbbi években történt a szerveren egy PHP verziófrissítés, aminek a változásait csak ímmel-ámmal követtem le (nem volt fókuszban a blog, de ezt nyilván észlelték akik követnek valamennyire). Most ránéztem újra alaposabban a site-ra, mert növelni akartam kicsit a reszponzivitást, és rájöttem, hogy egy csomó feature el van törve, meg én is eltörtem ezt-azt miközben ezt lefejlesztettem.
Meg arra is ráeszméltem így sok év szünet után, hogy atyaúristen mennyi minden funkciót csináltam itt
Ami mókás és örömteli felismerés volt. Úgyhogy elkezdtem playwright teszteket írni. Még nincs sok, mivel tegnap álltam neki.
Egyelőre egy külön privát github repóba tettem, szépen CI-ban futtatva, kapok emailt ha hasal meg minden. Később valószínűleg jobb lenne beletenni a blog főrepójába.
Van pár known issue, és azokat már úgy akarom meghegeszteni, hogy teszt is legyen rá.
Hát, nemtom meddig lesz erre időm, de most épp van.
CoreConsult - Your web application development company
PHP Javascript Angular Typescript Node.js Scala Android iOS React Java C# Python Rust Play Sangria GraphQL Kafka Hadoop MSSQL Elastic Mysql Oracle MongoDB Nightwatch Gitlab Bitbucket CI JIRA TDD SCRUM UX design + what not.
business@coreconsult.hu
Olivér Haszpra - haszprus@coreconsult.hu
Gergely Pász - pas@coreconsult.hu
How does this work?
Mostanában elég sok időm van, és sokmindent egyszerűen nem csinálhatok, pl nem sportolhatok. Meg minden. Meg egyébként is újra php-zek (vagy hackezek, ld. hhvm*) backenden, úgyhogy ezen apropóból nekikezdtem egy ideje a blog modernizálásának, és tervezem hogy kisebb-nagyobb időszeleteket erre fogok allokálni. Igazából új feature-öket nem tudom mennyire várhatok, először szeretném a meglehetősen legacy kódbázist egy picit modernizálni. Nem egyszerű feladat egyébként, és felmerülhet a but why
kérdés is. Hiszen pl nem több értelme lenne-e valami másik nyelven írni egy új motort, vagy valami egészen új dologba kezdeni. Igen, ezek a kérdések validak, a válaszom pedig az hogy most erre van lehetőségem így hosting terén, és egyébként sem akarom veszni hagyni a blogot. 2003 óta létezik, az annyit tesz hogy idén lesz 14 éves (nem semmi azért), és még él, lélegzik, és ezt meg is akarom tartani még egy darabig. Modernizációkra szükség van.
* HHVM is an open-source virtual machine designed for executing programs written in Hack and PHP. HHVM uses a just-in-time (JIT) compilation approach to achieve superior performance while maintaining the development flexibility that PHP provides. HHVM is developed by Facebook.
Úgyhogy ma:
Sun is shining)
Egyébként elgondolkodtam persze azon is - már egy ideje - hogy nem kéne-e valami pluszmelóba tolnom a szabadidőmet, pénzért. Well, it can happen on some day, addig meg igazából ennek is van értelme. Például tök jól flowba kerülök tőle.
Nem tudom használ-e még valaki régi RSS url-eket a blogról (ahol a címekben nincs benne az rss mappa, vagy rss_* a feedek címe), mindenesetre kipurgáltam őket. Ha szeretnéd frissíteni a feedjeidet, a https://blog.haszprus.hu/rss/ címen megteheted. Az rss/bejegyzesek, rss/kommentek, meg ilyesmi című feedek működnek a továbbiakban. (Ezek a címek már évek óta léteznek, az ennél régebbi feedcímeket dobtam ki.)
Egyébként nekimentem a motorháztető alatt egy masszív takarításnak ill. újrastrukturálásnak.
Nagyon érdekes megfigyeléseket tettem a projektünkön az API-val, a UI tesztjeinkkel kapcsolatban. Az API backendünk ugye Scala, találtam benne egy csomó refaktorálni való dolgot, Scalatrát használunk egyébként frameworkként, és természetesen nem mondhatom el a pontos refaktorálnivaló dolgot, de nagyon izginek ígérkezik, már elkezdtem dolgozni rajta illetve a többieket is bevontam, konzultáltam velük hogy szerintük miképp lehetne megoldani, hiszen én alapvetően eddig a UI-on tevékenykedtem, a Scalaban nem mélyültem el. Viszont most el akarok. Nem triviális a dolog, az ügyfél is kell hozzá egy kicsit, de bízom benne hogy tudunk alkotni valamit.
A másik rész ahol észrevettem dolgokat, azok a UI unit tesztjeink, úgy látom hogy ott is lenne mit megmódosítani, ez is izgalmasnak ígérkezik, vagy ha nem is izgalmasnak, de legalábbis nagy munkának.
Volt egy angular migráció is a hétvégén az amcsiknál, kíváncsian várom mit kapunk az új verziótól.
Itt megjegyezném hogy az angular 2.0 még sehol, de amúgy nagyon várom azt is, örülnék ha megjelenne, kíváncsi vagyok miket hoz magával, a már ismert részleteken kívül, a gyakorlatban is örömmel látnám.
A harmadik a Cucumber UI integration tesztek, na ezek végképp kívül esnek a hatókörömön, de lett a projekten egy új kollegina pár hónapja, aki nagyon jó észrevételeket tett, itt számos performance gaint könyvelhettünk el a tevékenysége során, és egy-két hiányosságra is fény derült a tesztlefedettséggel kapcsolatban.
Kezd sokkal izgalmasabbá válni ez a projekt, mint amilyen eddig volt, főleg hogy a csapatvezető 3,5 év után lekérte magát és helyette most új emberünk van. Van más új emberünk is, egész konkrétan két fejlesztő, akiknek az egyike ráadásul angol anyanyelvű, ami az angol jóval nagyobb fokú napközbeni folyamatos használatát követeli meg. Sokkal többet pair programmingolok az utóbbi időben, a projekten úgy általánosságban is megnőtt az együttműködés (pénteken négyen pörögtünk egy abszolúte brainfuck problémán és estére sikerült valamennyire megoldani legalább egy workarounddal, és kurva happy voltam). Úgy látom most mindenki bizonyítani akar, és megindult a projekten az eddigieknél egy jóval nagyobb mozgolódás, jobban élvezem mint eddig bármikor, és ennek nagyon örülök.
Hamarosan töltünk egymásról negyedéves értékeléseket, kíváncsian várom a feedbackeket a kollégáktól, és egyben örülök hogy én is írhatok, mert van mit.
Orca megkérdezte reggel hogy mizú, és egyszerűen fülig ért a szám miközben válaszoltam: minden cool, és most tényleg, minden cool
A dolgok nagyon jó irányba haladnak.
Volt nálam egy kolléga meg én is voltam valakinél az utóbbi 1-2 hétben és egyszerűen maximálisan pörgök szakmai dolgokon, néztünk kódot, tanultunk dolgokat, kurvajó volt.
Itthon a whiteboardomra felraktam egy csomó taskot magamnak erre a hétre is és jövő hétre is, és egyszerűen öröm ránézni, egy csomó mindenhez van kedvem, tanulni, és alig várom azt is hogy dolgozhassak (tudniillik hétvége van, és bár beremote-oltam péntek este kivételesen, de a hétvége azért mégse munkára van
), az EPAM-os projekten is, meg más projekteken is. Terveim is vannak, mindenféle.
Örülnék, ha a nap nem 24 órából állna, vagy ha a hét nem hét napból.
Jóval több dolgot van kedvem csinálni, mint amennyire időm jut. Happy times
Ma este úgy érzem hogy újra beleestem a programozásba
(Scala, Angular, JS, Django, PHP, so many tech stuff & so many possibilities)
Közben ez szólt és betoltam egy m&m's-es karamellás mcflurryt ![]()
Annyira kurvajó idő van...
És az új monitoromnak olyan gyönyörű színei vannak. Ahh, istenem ![]()
Tervek vannak.
Holnap amúgy vizsgám van de ez annyival érdekesebb
Client-side JavaScript App built using AngularJS wrote in CoffeeScript, served from the Play 2 Framework and using document persistence with Reactive Mongo a non-blocking Scala client for MongoDB.
Úgy érzem, mintha a lehetőségeim végtelenek lennének
Vuhúú voltam ma angolon jeah
És tanultam scalát jeah
Nemsokára meg én tanítok majd egy kis php-t jeah
Tegnap ötödölőzni akartunk, úgyhogy gyorsan le is programoztunk egyet angularban.
(Meg lehet nézni!
) Asszem életem kb első játéka. A kódot senki ne nézze, csak gyorsan összedobtam a kiscsajnak egy játékot.
Felkértek, hogy reviewzzak egy készülő könyvet, a PHPStorm Cookbookot
Na jó, az lesz, hogy összehozok egy local environmentet mégiscsak a blognak. Erre az alapkésztetés az, hogy nagyobb feature-ök lefejlesztésére nagyobb hajlandóságot éreznék, ha nem lenne folyton a nyakamban az, hogy elcseszek valamit productionben.
A második nagy késztetés, hogy előbb-utóbb portolni kell újabb php verzióra a blog motorját, és ez nem annyira frankó élőben.
Amúgy a dolog marha izgalmas, csomó deprecated dolog időközben kivezetésre került, úgyhogy jönnek a factoryk és a különféle elágazások környezet mentén.
Muy excitement, mucho power! Sose gondoltam volna, hogy egyszer lesz ez még ennyire izgalmas.
Most pedig péntek este van, sörre fel!
Csak egy gyors angular vs php view kód összevetés
PHP:
Angular:
Sasszeműeknek feltűnhet hogy az angular kódom egy picivel kevesebbet tud, ettől függetlenül tisztább, szárazabb érzés.
Szóval a YOULOG most kőkemény angular js lett:
Oh yeah.
youlog is based - currently - on php, css, mysql
Kezd kurvajó lenni ez a dolog
Anyone interested in a fancy online keyword based diary (lifelog)?
Az most senkit ne zavarjon hogy a napok még nem jó sorrendben jelennek meg.
Mai állat fejlesztésünk: youlog.
Mint tudjuk régóta csinálok fancy naptárat magamnak arról, hogy miket csináltam. Most egyelőre az van hogy fel tudom címkézni a blogon a napjaimat faszán.
Aztán hosszú távon szeretném megcsinálni vele ugyanazt, amit most excelben tudok:
A cucc egyelőre a saját useremre van limitálva, de lehet hogy felkínálom még valakinek érdeklődés esetén.
Ami nagyon fontos, és ami a fő motiváció, hogy motiválni akarom magam, hogy csináljak dolgokat. Pl. kondizzak, fejlesszek, ilyesmi.
A háttérben meg mellesleg csináltam hozzá egy kis ActiveRecord implementációt szórakozásból.
A fenti kód már önmagában validálja az id és a date mezőket, dob kivételt ha nem jók, stb. Nyilván a HfModelben van a lényeg, csak megmutattam hogy ilyen kis lightweight cuccka lett, a használata pedig:
Oh, I heart PHP!
Mai productivity eredmény: melóban egyértelműen jobban haladtam fb nélkül, itthon pedig leporoltam a januárban félbehagyott scala play blogengine projektemet
(Elavultak a cuccok alatta, már nem fordult IntelliJ-ben (ez nem egészen tudom hogy hogy lehet, habár gondolom úgy, hogy a play konzol valamit update-elt magán, az IntelliJ meg nem követte), rendbe kellett rakni. Ráment kb. 2 óra, de megérte.
)
A miranda ng-t pedig még tovább customizáltam, egész barátságos lett. (Atom minimál.)
23:02 Na még egy gyors bejegyzéslájkolós feature lefejlesztése belefért. 0.1-es verzió, egyelőre lehet lájkot leadni, és kiírja hogy hányan lájkolták eddig a bejegyzést. Oje!
Majd lesz fullosabb később. (Ja és csak ha belépett user vagy.) Igen, igen, tudom hogy volt már hasonló, de ez kicsit másmilyen lesz, meg jobbabb is lesz.
Mai fejlesztéssel töltött idő itthon: 3-4 óra. Roxx!
Istenem, végre.
(Mert persze be kellett tolni egyből egy új 0-ról írt frameworköt is az új feature alá, nem lehet csak úgy. Rég nyúltam a blog kódjához na, és már mások az elképzeléseim.)
Ja és itt kikúrt continuous delivery van ám, annyira hogy nincs localhoston meg sehol tesztszerverem, a blog úgy jó egyből ahogy megírom.
Nem tesztelni kell, hanem jó kódot írni, basszátok meg.*
* A szerző a pókerarcos humor hazai élharcosa. Ismeri és gyakorolja a TDD-t, de ez itt most nem az a projekt, itt tényleg izgibb egyből productionön futó kódot írni. Ennek is megvan a szépsége, ha valaki nem hiszi, próbálja ki dev/test környezetek nélkül fejlesztenie az akármilyen rendszerét.
Eddig nem használtam a Traits feature-ét a PHP-nek, megnéztem most vele egy Hello Worldöt. Semmi extra.
<?php
trait Hello {
function sayHello() {
echo "Hello";
}
}
trait World {
function sayWorld() {
echo "World";
}
function sayHello() {
echo "Szia";
}
}
trait HelloWorld {
use Hello, World {
World::sayHello insteadof Hello;
}
function sayHelloWorld () {
$this->sayHello();
echo " ";
$this->sayWorld();
echo "!";
}
}
class Main {
use HelloWorld;
}
$m = new Main();
$m->sayHelloWorld(); // Szia World!
Amúgy kéne írnom egy überblog android appot, legalábbis az admin dolgoknak. Csak azért ennyire fb-központú vagyok, mert ott könnyebb megszerkeszteni a dolgokat. Mind mobilról, mind innen netről.
Mondjuk hozzáteszem, hogy nagyobb közönséget is érek el vele, legalábbis jelenleg. (Ha akarják, ha nem, ahah!)
Mindenesetre az Android app helyett most egyelőre elscalazgatok, azzal is elkezdtem játszani. Kellemes, szimpatikus.
I've released on github a simple contact management concept based on mongodb. The goal was to write as little code as possible and still give the user an amount of functionality.
Later I'll try to create a longer description about the project. Until then, if you are interested, please look at how lightweight the models and the controllers are, and still how much functionality they give to the user.
Megjelent a PHPStorm 4.
PHP 5.4 language features support Code coverage for PHPUnit Drupal coding style support ECMAScript Harmony support PHP code sniffer integration New PHP code inspections Smarter JavaScript completion
Things I like:
(Of course there are other things too.)
+1 lol from the changelog:
<?= is now always available, regardless of the short_open_tag php.ini option.How hard they were fighting against short open tags… I think this is similar to HTML 5 where you don't have to close your tags despite the whole community was forcing strict XHTML for years
because it's better.
Na ez például egy remek szakmai fejlődési program.
Igazából nem kéne meglepődnöm. Abban a szobában kb. 40 projektnek a fejlesztése zajlik, rengeteg külsős cégnek adnak ki megbízásokat a senior fejlesztőink. Csupa ilyen arccal vagyok körülvéve, juniorok nem nagyon dolgoznak a Sanomában, mert a legtöbb projektet kizárólag külső erőforrásokkal fejlesztik, plusz a hotfixeket belül, meg a deploy, üzemeltetés, ilyesmi. A lényeg hogy rengeteg tudás koncentrálódik körülöttem, és ha jól csinálom akkor rengeteget profitálhatok az itt eltöltött időből. Sajnos ebből a szobából hamarosan ki leszünk emelve egy kevésbé szakmai közegbe, de lobbizni fogok hogy tarthassam minél jobban a DPO-s kapcsolataimat.
Vettem egy phpstorm licenszet.
Jóság.
Nu, Gábortól megint tanultam egy kis Zend Frameworköt, de igazából az eddigi rátekintéseim eddig mindig hiányérzettel zárultak, nem igazán érzem hogy ez miért jó, valahogy a Symfony úgy jobban egyben van…
Used technologies in our new project:
![]()
Ott voltunk ezen is Orcával és PAStheLoDdal. ![]()
Szubjektív véleményem: nagyon hardcore advanced cuccot vártam, ehhez képest kicsit bme-sre sikerült, legalábbis az első egy-két előadást a magam részéről túl lassúnak ill. bealvósnak éreztem, a verziókezelős és a scrumos teljesen triviális dolgokról beszélt (szerintem elhibázott tematika). Volt viszont nagyon kellemes meglepetés is, éspedig a PHP Security, ami nagyon élvezetes volt (erről a témakörről még valszeg többször ennyit szívesen hallgatnék), illetve a HTML5 bemutató, ami viszonylag meglepő módon még mindig tudott egy csomó újdonsággal szolgálni a HTML 5 konferencia után is.
Amik voltak:
Gondoltam eljátszom a twig template kezelővel, ami erősen a symfony 2-höz és fabien potencierhez kötődik, tekintve hogy ő az atyja mindkettőnek és ez a symfony 2 default templating engine-je.
A telepítés igen könnyű pearrel:
(Egyébként nem muszáj pearrel telepíteni.)
Hozzuk létre a kis hello world sablonunkat:
Hello {{ name }}
The date is {{ date }}
The time is {{ time }}
Mentsük el templates/hello.tpl-ként.
A template-et adattal kiszolgáló php a következőképp fog kinézni:
Ez ennyiből már működik is. A twig lehetőségeibe mélyebben nem megyek bele, aki használt már bármilyen template engine-t, annak sok újat nem fog mutatni.
Nemrég kezdtem el picit ismerkedni a CakePHP MVC frameworkkel, igazából egyáltalán nem célom ismertetni a képességeit vagy bármi hasonló, mindössze megragadnék egy dolgot ami megtetszett. A dolog nem újdonság, mint ahogy a CakePHP sem az, sőt.
Induljunk ki onnan, hogy már megvannak a tábláid a db-ben, amit még korábban létrehoztál, hogy Cake-et kezdtél volna használni. Nem feltétlen tipikus felállás, tudom.
Megmondod az érintett kontrollerednek egy tagváltozóban, hogy
$uses = array('Restaurant', 'Place');
, aminek a hatására a kontroller a Restaurant és a Place nevű modelleket példányosítani fogja és hozzárendeli a $this->restaurant ill $this->place változókhoz a Controlleren belül.
Amennyiben a megfelelő könyvtárban nincs Restaurant ill. Place modell (az ezekhez tartozó php fájl és osztály), akkor megnézi, hogy a db-ben létezik-e restaurant ill. place nevű tábla, és ha igen, akkor ezekből generál on-the-fly egy-egy modellt.
Lekérdezi tehát a db-ből a táblák oszlopait, és rögtön használhatod is valamennyi tagfüggvényt rájuk, mint pl. megkeresheted az 5-ös id-jű éttermet:
$this->restaurant->findById(5);
Nem csak id alapján kereshetsz, hanem bármi egyéb oszlopnév alapján is természetesen, tehát pl. $this->restaurant->findByType('lacikonyha') hívás is teljesen valid.
Nekem ebben az tetszik mondjuk egy symfonyval szemben, hogy a modellt nem kell generálnod, létrehozza neked on-the-fly, aminek különösképp ott érzem előnyét, ha valami változik az adatbázis sémában (nevezetesen nem kell újragenerálgatni a modelleket, ami marha kényelmes dolog). Nyilván hátránya, hogy egy IDE sem fogja kitalálni neked, hogy vajon milyen tagfüggvényeket hívhatsz meg az ilyen módon használt modelljeiden.
IRCQuote fight! In the ring:
| kúúúúúúúúúrvajó |
Brutál, nagyon impresszív
Komoly lelkesedéssel díjazom. ![]()
Múlt héten a CodeIgniter Framework megismerése volt terítéken, ma pedig kutattam egy kicsit, amit a napokban még folytatni fogok full text search témában, érintve, de nem korlátozódva a következőkre:
Implementáltam egy a Zend Frameworkben található Zend Search Lucene-t használó megoldást (abszolút experimentális jelleggel, index buildelés és lekérdezés) CakePHP Framework alá beültetve.
Megjelenítési réteghez úgy tűnik 960 Grid System lesz a választottunk.
Itthon eközben symfony frameworköt nyomok továbbra is Doctrine ORM-mel.
Izgi mind. ![]()
SEO power.
Tegnap ledemóztam Zolinak a symfony - doctrine duó YAML alapú (schema.yml) adatbázis- és modellgenerálási képességeit, illetve hogy miként lehet ebből formokat és komplett modulokat legenerálni, valamint miként lehet testreszabni ezeket. Ahogy láttam, impresszív volt.
Mondjuk szerintem is az.
A következő webalkalmazásomhoz symfonyt választottam keretrendszernek.
IRCQuote fight! In the ring:
voltam epamosokkal bulizni az este, szilárddal feljöttünk előtte hozzám inni aztán gáborékhoz csatlakoztunk a corvin tetőn. szilárddal beszéltünk az önértékelési problémáimról, leírtam 3 gondolatát:
-
nagyon értesz az emberekhez és nagyon is akarsz érteni hozzájuk-
szard le mások véleményét-
hidd el h a felhozatalban elég magas szinten állsz. akik php-vel foglalkoznak, kb. a venere csapata az akit az 5 év alatt, amióta dolgozom... alkalmaznék...
Közben rámírt Gyuri (jedlikből):
Lesz ilyen a PHP-ben, kis apróság, de valami amire régóta vágyom ![]()
Csapatvezető leszek a site csapatban a Ustreamnél, úgy tűnik.
Valid-e az ovjektum?
Amúgy nem jó az UML, de csak most olvasgatom hogy hogy is kéne.
21:43 ilyen lett:
Irgalmatlan tempóban készül a Haszprus PHP Framework… ![]()
(Önlabra lesz, egyelőre van benne fasza formgenerálás, mvc (mégpedig kicsit smarty-style), minden ami kell… Nem használ fel korábbi cuccaimat, written from scratch, inspired by symfony and TRES.)
(Munkáltatóm figyelmébe: a cuccot itthon készítem ingyé nem kevés időben (pl. most 4:50-kor végzek vele és kb. tegnap 18 óta nyomom, az hány elszámolatlan óra is egy nap alatt?) és maximálisan fel fogom használni a munkámban. Jól.)
A cégnél az első feladatom egy olyan script optimalizálása volt, amely 12-től 30 vagy akár még több MB-ig terjedő XML állományok alapján hajt végre nagyságrendileg 100-500e egymással összefüggő SQL insertet (értsd: mély és széles xml-fa).
Az eredeti progi egy 30 megás XML-lel kb. 2 perc 40 másodpercnyi munkát adott az apache.exe-nek (ennyit foglalt a prociból tehát az apache), miközben a memóriahasználat az alapjáratú 27 MB-ról felment 558 MB-ra. A program teljes futási ideje 383 másodperc volt.
Elég sok időt eltöltöttem azzal, hogy egyrészt a program logikáját megértsem, másrészt utána nézzek, hogy vajon van-e valami hatékonyabb XML parser. Miután nem találtam a használt megoldásnál jobbat (tekintve hogy az se a teljes dokumentumfát tárolta a memóriában), már majdnem ott kötöttem ki, hogy ezt bizony nem lehet (vagy én nem tudom) optimalizálni (bár persze kételkedtem), ehelyett kicsit kitesztelgettem, hogy hogyan is működik a php-ben a változók és objektumok megsemmisítése (ld. __destruct), és a megfelelő stratégiai helyen mért csapás eredményeként a program most nem növeli az apache alapjáratú memóriafoglalását egy megával sem
(Érdekes módon az unset nem segített.)
Azaz az én verzióm a 30 megás XML-lel ugyanúgy 2 perc 40 másodpercig tekeri az apache.exe-t, azonban összesen csak 358 másodpercig fut (fél perc nyeremény itt, miközben sebességre még nem is optimalizáltam), és ami a lényeg, hogy 27-ről nem 558 MB-ra nyomja fel az apache memóriahasználatát, hanem mindössze 29-re. Nem kell mondani, hogy ez mennyire előnyös egy olyan környezetben, ahol más dolgok is futnak (ti. ez egy webszerver).
Amikor nekiálltam a dolognak, egy nagyságrendi változást akartam volna elérni, aztán ahogy beleástam magam, megelégedtem volna akár egy memóriafelezéssel is, végül már majdnem teljesen feladtam, de arra álmomban sem gondoltam, hogy sikerül a memóriahasználatot úgy ahogy van megszűntetni
Ettől igen jó kedvem lett ![]()
Rulz.
Ma az adminfelületen a logok közé benézve a következő ablak villant fel:
Gondoltam biztos valamelyik firefox extension bugzik. De nem. Valaki egy lapletöltésnél user agentnek azt bírta megadni, hogy
<script>alert(1)</script>
Ofkorsz a user agentek biztonságosan kerülnek az adatbázisba egy $db->safe_string() konverzión keresztül, mert nehogymár valaki ott kezdjen sql-t injektálni, de arra még nem gondoltam, hogy valaki html-t vagy js-t fog becsempészni így az oldalra. Trükkös.
Kvízjáték: mit jelent az alábbi PHP hibaüzenet és hogyan lehet kiváltani? ![]()
Parse error: syntax error, unexpected T_DEC, expecting T_PAAMAYIM_NEKUDOTAYIM
Google nem ér.
Először arra gondoltam, létrehozok egy bejegyzést a Propelnek, de kezdetnek inkább csak egy ilyen általánosat… ki milyen külső cuccokat használ php alapú webfejlesztéshez? Nem projektspecifikus cuccokra gondolok (pl. free webgaléria, stb), hanem általánosan használható, beépíthető dolgokra (mint pl. adatbáziskezelő réteg, template rendszer).
Én elsősorban a bloggal szórakoztatom magam, és itt nem az a cél hogy gyorsan fejlődjenek a dolgok, hanem hogy magam fejlesszek ki mindent. Hobbiból. Ennek megfelelően eddig nem is nagyon vettem be külső fejlesztéseket a projektbe, egy éve bekerült egy Smarty (ami nem jött be végülis), és most nemrég a prototype.js, igaz ez nem php, hanem js/ajax. Na ilyesmikre gondoltam. Nyomassad, miket használsz, mire jó, stb.
Hardcore kocka bejegyzés következik, kérjük álljanak hátrébb.
Szerinted melyik a jobb kód? (Katt a képre, látni fogsz egy alsó és egy felső verziót.)
Update nov. 13. 10:04: már három verzió lapul a kép mögött! Frissítettem Kristóf javaslatával.
Gyakran előjövő probléma, hogy a látogatónak szeretnénk megadni a lehetőséget a táblázataink rendezhetőségére. Erre nyújt megoldást a draw_table_from_array függvényem, amelyet egy munkám során hoztam létre. Nemcsak egyforma (teljesen css-ből formázott) megjelenést nyújt a táblázatoknak, de erőfeszítés nélkül lehetővé teszi, hogy bármely oszlop szerint rendezzük őket. Egy-egy tábla előállításához a kód pusztán ennyi, az sql lekérdezéstől a felhasználó által rendezhető tábla megjelenítéséig:
Az eredmény:
A dolog működése élőben is kipróbálható [itt egy link volt, közben meghalt].
Az a blogra pakolt lightweight galéria még mindig lightweight de egyre durvább lesz… Most már tud onthefly, oldalújratöltés nélkül album nézetet is. Ilyet:
Nomeg billentyűzetről jobbra-balra lapozgatni, ha valaki nem lenne naprakész a kommentekből.
Az a helyzet hogy teljesen lightweight módon megoldottam egy atombrutál full-featured highly advanced client-side cached galériát, amihez se külön db nem kell, se adminfelület, se semmi, full automatikusan onthefly ráépül a bejegyzésekre. 37 sor php (!), 60 sor html, 121+64 sor javascript (és 139 sor css). Az egész cucc 10 KB. Csak viszonyítás képpen a Haszprus Private Gallery 110 KB, amiből az adminfelület 26 KB - ez utóbbi ugye itt nem is kell.
Ki lehet próbálni (akárhol az ablakban katt, előjön az album nézet), ráadásul egy olyan képgalérián, ami egy egyelőre nem is publikált bejegyzésből táplálkozik (így a bejegyzésre mutató link nem fog működni (számotokra)… ez nem bug).
Örülnék, ha adnátok valami feedbacket, hogy mégis milyen lett.
ie-ben az album nézet nem jelenik meg de pillanatnyilag lesz*rom. a jó hír hogy valszeg ez elég könnyen javítható, csak rá kéne nézni hogy pontosan mi a hézag.
Update szep. 03. 01:11: na megy.
Íme az überblog legújabb, highly advanced feature-e, a képlapozó.
Semmiféle adatbázis-módosítás nem kellett hozzá, egyszerűen kideríti hogy a képet melyik bejegyzésből linkelték (mégpedig erőforráskímélően, de még lehet rajta fejleszteni), megnézi hogy a bejegyzésben mely képek veszik körbe őt (azaz melyik kép van előtte és utána (ezen is lehet gyorsítani)), belinkeli azokat, sőt belinkeli magát a bejegyzést is, így megkönnyítvén a navigációt. Ha jók lesztek akkor előbb-utóbb talán megcsinálom javascriptesen széjjelcache-elve is, mint a private galleryt, 0 sec késleltetéssel, lapújratöltés nélkülire.
Ha az egeret az előző/következő link fölé viszed, kapsz egy kis thumbnailt is arról, hogy mégis milyen képre jutsz a linkre kattintva. Mindez nem feltétlen lóg rá egyébként a képre, alapvetően 1280*1024-re illetve afölé van kitalálva mindez, ahol rálógás nincs, sőt az egész kép kifér.
Azt kell mondjam, ez kurvajó lett. Elégedetten dőlök hátra. Vegyük észre hogy ez egy lightweight galleryt akaszt a blogra, amely így 2.9-es stádiumba léphet.
A dolog működését megtekintheted például itt, vagy nyilván bármelyik bejegyzésnél, ahol van mik között lapozgatni.
Update aug. 23. 18:18: lett 0 sec delayes lapozás, cache-eléssel, oldalújratöltés nélkül. Tudnivalók:
Ki akarjuk bányászni egy időjárásjelentő oldalról hogy hány fok van, hány fok lesz, stb.
/**
* $source szovegbol kibanyassza a
* $id id-ju div erteket es
* $type tipusra castolva visszaadja
*/
function get_value_by_div_id($source, $id, $type) {
$matches = array();
$regexp = "<div.*?id\=\"$id\".*?>(.*?)<\/div>";
preg_match("/$regexp/s", $source, $matches);
settype($matches[1], $type);
return $matches[1];
}
Így pl.
A kimeneten:
Hőmérséklet: 26 fok (érzésre 28 fok).
Adottak a hét napjai (H, K, Sze, Cs, P, Szo, V), valamint egy adattábla, benne minden rekordhoz két nap. Számítsuk ki, hogy a két nap között hány-hány nap van. (Pl. hétfőtől péntekig, majd péntektől hétfőig eltelő napok száma.)
A nem javasolt
megoldás: veszünk egy külső switch case szerkezetet, amelynél az eseteket az első napok szerint alakítjuk. Hét eset. Majd ezek mindegyikében egy újabb switch case, aszerint, hogy a második nap mi. 72 = 49 eset.
switch ($elsonap) {
case 'H':
switch ($masodiknap)
case 'K': echo '1 ill 6 nap van koztuk'; break;
case 'Sze': echo '2 ill 5 nap van koztuk'; break;
...
case 'K':
switch ($masodiknap)
case 'H': echo '6 ill 1 nap van koztuk'; break;
case 'Sze': echo '1 ill 6 nap van koztuk'; break;
...
...
}
Ez tényleg nem túl jó, egyrészt a 49 elágazás miatt, másrészt mert ha mondjuk angolul is ki akarjuk írni az eredményeket akkor már 2*49 elágazásunk lesz. Egy fokkal jobb megoldás, ha a napokhoz számokat társítunk, majd ezeket kivonogatjuk egymásból mod 7:
switch ($nap) {
case 'H': $n = 1;
case 'K': $n = 2;
...
}
Csakhogy ezt a társítást lehet switch case nélkül is, és ezúttal egy végleges, immáron meglehetősen rövid és komplett megoldás:
function eltelt_napok($napchar1, $napchar2) {
$napok = array('H' => 1, 'K' => 2, 'Sze' => 3, ...);
$nap1 = $napok[$napchar1];
$nap2 = $napok[$napchar2];
$diff1 = mod(max($nap1, $nap2) - min($nap1, $nap2), 7);
$diff2 = mod(min($nap1, $nap2) - max($nap1, $nap2), 7);
return array($diff1, $diff2);
}
A mod fv természetesen megvalósítandó vmi tetszőleges módon. Lehet hogy a php-ben van is rá vmi, én hirtelen nem találtam, úgyhogy:
function mod($n, $q) {
$n %= $q;
if ($n < 0)
$n += $q;
return $n;
}
Update 17:13: sőt a mod fv is elhagyható, ld. tbela kommentje.
A cucc naponként egy text/xml adatbázist
dolgoz fel, amiben el vannak mentve a spamküldés részletes körülményei. Ebből a logolásból egyébként sok érdekes tapasztalatra tehetünk szert, így pl. az alábbiakra:
kitöltöttmezők között olyanok is, amik már rég más névre hallgatnak (így pl. az anon_nick neve régóta vendeg_nev, mégis jönnek spamek kitöltött anon_nick mezővel - érdemes hát betenni a szűrési feltételek közé azt, hogy amennyiben van anon_nick a $_REQUEST-ben, akkor nyilvánvalóan spammel van dolgunk).
pwnevű input mezőbe is url-t próbálnak beírni aztán csodálkoznak hogy nem jelenik meg a hozzászólásuk…
Na szóval itten gondolkodtam hogy miként lehetne backupolni a bejegyzéseket, de csak szépen finoman, abban bízva, hogy remélhetőleg sosem lesz a backupra szükség.
Először arra gondoltam, egy fájlba szépen kiírom a bejegyzések szöveg mezőjét beküldéskor, oszt jóvan.
Második nekifutásra azonban készítettem egy functiont ami xml-be kiírja a bejegyzéshez kapcsolódó összes adatot, de nemcsak itt használható, hanem bárhol, rekurzívan egy akár többszíntü arrayt kinyom egy gyönyörüen formázott plain text alapú xml fájlba.
/**
* rekurzÃvan xml-be fejt egy akár többszÃntü array-t
*/
function arrayToXML($array, $level = 0) {
$return = "";
$indent = "";
for ($l = 0; $l < $level; $l++)
$indent .= "\t";
foreach ($array as $key => $val) {
$return .= "\r\n";
$return .= $indent;
if (is_array($val))
$val = arrayToXML($val, $level+1) . "\r\n" . $indent;
$return .= "<$key>$val</$key>";
}
return $return;
}
Majd pedig egy elegáns húzással:
$backupfile = new File(....); $content = arrayToXML($_POST, 1); $content = "\r\n<post>$content\r\n</post>"; $backupfile->appendContent($content);
Az eredmény egy konkrét példája:
<post>
<b_id>2439</b_id>
<szoveg><p>Müködése a kommentben.</p></szoveg>
<b_cim>Quoter function</b_cim>
<submit>Ment publikusan</submit>
<gall_categ>0</gall_categ>
<gall_entry_title></gall_entry_title>
<b_commentable>on</b_commentable>
<categ>
<1>on</1>
</categ>
<b_privszoveg></b_privszoveg>
</post>
Nos, 404-es errordoc esetén az apache nem adja át az url-paramétereket a php scriptnek (azaz nem jön létre se a $_REQUEST, se a $_POST, se a $_GET tömb), ez értelemszerüen problémákat okoz a meglévő scriptekben.
A $_GET pótlása nem túl körülményes. (Illetve én a $_REQUEST-be írom, mert azt használom.)
$tmp_request_parameters = explode('&', $URI);
foreach ($tmp_request_parameters as $trp) {
$t = explode('=', $trp, 2);
$_REQUEST[$t[0]] = $t[1];
}
A $_POST-ra egyelőre nincs ötletem.
Ami pedig még jó lenne, hogy pl. egy form az elküldendő adatait az url-hez szépen /.../ formában írogassa hozzá. Valszeg előbb-utóbb erre is sort kerítek, a megoldás gondolom valami script lesz, ami a form adataiból egy window.location változtatást visz véghez submit helyett.
Jó, persze, a wiw meghívókérés az nem spam valójában, de ez most tökmindegy.
Tekintve, hogy a blogon pillanatnyilag összesen csak egy különösen spamelt bejegyzés van (mégpedig az iwiwről szóló), ezért nem építek semmi adatbázis-cuccot a dolog mögé, egyszerüen forráskódba belegányolom. Lehet hogy gány, de így gyors, így egyszerü, és tekintve hogy ez a lista évente bővül egy bejegyzéssel, ezért könnyen karbantartható is.
/* spamszavak száma: spamfactor */
$spamwords = array("http://", "great", [...]);
$spamfactor = 0;
foreach ($spamwords as $spamword)
if (strpos($rq['szoveg'], $spamword) !== false)
$spamfactor++;
/**
* különösen spamelt bejegyzések esetén nagyobb a valószínűsége,
* hogy spammel van dolgunk... */
$spammed_posts = array(2226);
if ($spamfactor > 0 && in_array($rq['bejegyzes_id'], $spammed_posts))
$spamfactor++;
Majd ha marha sok időm lesz, lehet, hogy átültetem db alapúra ezt a spam, meg badword, meg spammed_posts témát, de ugye akkor kell hozzájuk kezelőfelületet írni és az rögtön rengeteg vesződséggel jár, és a karbantartás sem egyszerübb végülis mint forráskódba néhanapján belehegeszteni egy-egy új szűrt szót vagy id-t.
Na nyilván lehetett erre számítani, de azért említsük meg, hogy a php laborházim 14+45 = 59 pont lett, ez a maximum amit el lehet érni, és egyébként 32-től már amúgy is ötös
(Igen, 32-től!) Mondjuk azt nem vágom, hogy hova tűnt a valid xhtml-ért, error_reporting e_all-ért és register_globals off-ért járó +4 (vagy +6?) pontom, valszeg a javító úgy volt vele hogy nincs rá nagy szükségem ![]()
Gratulálok. Talán a legprofibb megoldás, amit eddig láttam. Látszik, hogy volt már tapasztalatod a témában. [...]
Na jó, mit verjem magam, tényleg elég sokat foglalkozom a témával. Akik esetleg ezt szeretnék az orrom alá dörgölni egy hozzászólás formájában, hagyják ki, tisztában vagyok vele.
Meg kell mondjam, nagyon emberségesnek tartom az Adatb laborházik javítását, nem volt még olyan házi amihez ne gratulált volna a javító. Persze lehet hogy ez az ő egyéni érdeme. Mindenesetre respect & thx, jólesik.
Ha le akarod mérni, tedd be a lapod elejére ezt:
ob_start();
function microtime_float() {
list($usec, $sec) = explode(' ', microtime());
return ((float)$usec + (float)$sec);
}
$time_start = microtime_float();
A végére pedig ezt:
$time_end = microtime_float(); $time = $time_end - $time_start; echo 'Lapgenerálás: ' . $time . 'mp'; ob_end_flush();
Ez a kód azért jó, mert az ob_startnak köszönhetően nem számítja bele az időbe a lap letöltődését. Enélkül amit kapnál, az függne a szabad sávszélességedtől. És az nem lenne jó.
(A kód nagyrészt innen származik, de a dolog értelmét szerintem az ob_start - ob_end_flush kiegészítés adja, anélkül a script helyett szinte a saját sávszélességedet méred.)
class Container {
var $elements
var $pointer
var $length
function Container()
function addElement($element)
function length()
function getElement($i)
function getLastElement()
function getFirstElement()
function getNextElement()
function removeElement()
function setPointer($i)
function forAll($function)
}
class Comments extends Container {
var $picOfUser
function Comments()
function getCommentsByPostId($post_id, $order, $from, $to)
function showHTML()
}
class Comment {
var $row
function Comment($row)
function showHTML()
}
A hajnal óta elkövetett változtatásokat jelöltem. Logikusan a showHTML mellé kerülni fog egy-egy showRSS function.
ha igazán OO akarsz lenni, akkor egy komment egy class, aztán csinálsz egy generikus container vagy lista class-t, és származtatsz belőle egy olyan class-t, amely csak kommenteket tartalmazhat
Tamás - Obi kérdés
Megvalósítva mindhárom
(Preview Release 1) A megjelenítést még nem írtam meg szépre, de ott már csak néhány változót kell lecserélni. Ami eddig kész:
class Container {
var $elements
var $pointer
var $length
function Container()
function addElement($element)
function length()
function getElement($i)
function getNextElement()
function removeElement()
function setPointer($i)
}
class Comments extends Container {
function Comments()
function getCommentsByPostId($post_id)
function show()
}
class Comment {
var $row
function Comment($row)
function show()
}
Ez utóbbi show() még tiszta bug, értelemszerűen.
Objektum-orientált PHP (I'm lovin' it), MySQL 4 (I'm lovin' it, too) és némi egyéb strukturális változtatás (which I'm also lovin') miatt: Haszprus überblog 2.4. A verzió a későbbiek folytán fog kiteljesedni mivel nyilván nem cseréltem le mindent egy hét alatt.
Ha a kommentbe írtok egy olyat, hogy pl.
#10: hogy érted ezt?
Akkor, a #10-et automatikusan linkelni fogja a 10-es kommentre. Sőt, onnan egy újabb linkkel pedig visszatérhettek oda, amelyik kommenttől jöttetek. További részletek a képre kattintva, vagy a hozzászólások során megtapasztalva. (A dolog visszamenőlegesen is műxik a blog kezdete óta érkezett összes kommentre.)
A dolog műxik IE6, Firefox 1.5, Opera 8.5 alatt, többit nemtom, de talán nem is érdekes.
Meg lehet benne választani, hogy milyen témaköröket kívánsz olvasni, mégpedig checkboxok segítségével annyit, amennyi jólesik. Hasznos kombináció pl. a buli + barátok + kirándulás.
A kategóriánkénti szűrés havi archívumon belül működik. A hónapok közti lapozgatást kicsit megkönnyítettem azzal, hogy az archívum tetejére, a kategóriaválasztó alá is helyeztem egy archív-linktárat.
Legyen ez a blog 2.0-s verziója.Miért is? A főbb okok: