Command line script fara $argv

php
cli

(George Grigorita) #1

Am primit un test pentru o pozitie de front-end in care am urmatoarea cerinta*:

Create a command line script that accepts an image file path, width, height, and output filename. It will open the source image, resize it to the new width/height, and save it on the destination filename. The script should handle proportional resizing when either one of the width or height is not provided. You can NOT use $argv.

Fiind pe front-end in ultimii ani, n-am prea lucrat in PHP. Dar am citit, cautat, citit din nou, si chiar nu-mi dau seama cum se poate crea un script care sa ruleze in CLI fara argumente, sau cum sa fie transmise argumentele catre script fara $argv.

*trecem peste faptul ca nu-mi dau seama de ce apare testul asta la front-endā€¦


(Georgiana Gligor) #2

getopt pentru o experienta buna
poti face un symfony command ca sa ai si output coloring


(George Grigorita) #3

Exact despre symfony command citeam acum, dar aveam impresia ca tot argv foloseste pentru console input.


(Cosmin Popescu) #4

argv este un vector de argumente. Scriptul tau poate sa primeasca mai multe argumente
Cred ca te-ar ajuta si biblioteca Imagick.

Imagick::resizeImage pt resize de imagine

O posibila idee
Pas 1 - citesti path-ul imaginii
Pas 2 - folosesti biblioteca respectiva
Pas 3 - salvezai imaginea procesata

Pt partea ā€œproportional resizingā€ am gasit asta si asta. Ultima este in js, dar la unul din raspunsuri ai si o explicatie matematica

Spor :slight_smile:


getopt este si in C si in bash


(IstvƔn F.) #5

Tu aplici pentru o pozitie de frontend la firma lui peste prajit ?

N-are niciun sens, argv e standardul prin care accesezi argumentele pasate in fiecare limbajā€¦

Eventual ai putea lua pid-ul shell-ului care a rulat comanda, sa iei comanda rulată ultima dată cu memory injection si iei cu regex argumentele.
Unele bash-uri au direct acces la history cu o librarie.

Singurul sens ar fi obligatia ca argumentele sa poata fi si stream-uri.


(Cosmin Popescu) #6

offtopic
Daca ar face cum ai zis tu, ar merita sa fie angajat cu felicitari !

Am carpit acest cod

<?php

$args = getopt("p:r:"); //argumente pt script. se pot aduga mai multe optiuni

$image = $args['p']; //accesare argumet dorit. in acest caz path-ul imaginii

$result = $args['r']; 

$imageblob = new Imagick($image);
$imageblob->thumbnailImage(500, 500);
$imageblob->writeImage($result);

Asa se apeleaza php test.php -p IMG_0386.JPG -r cropped.JPG
:slight_smile:


Pt transferul pozei din terminal am folosit transfer.sh
Nu prea vad ca cerinta sa aiba o legatura cu frontend-ul, dar trecem peste :slight_smile:


(eduard) #7

Ai putea citi argumentele dintr-un fisier aflat in folderul curent (scriptul putand fi apelat in oricate foldere se doreste).

Totusi este mult mai probabil sa se doreasca un script CGI (FastCGI, etc) care sa accepte argumentele in variabile de mediu.


(Horia Coman) #8

Late to the party but ā€¦ cel mai bine ii intrebi sa-ti clarifice situatia. Eventual poti sa-i intrebi de ce anume iti dau chestii in care nu pretindeai competenta sau care nu se aplica rolului.

In interviuri trebuie si tu sa-ti dai seama despre cum e compania si daca e OK pentru tine, la fel de mult cat este pentru companie sa-si dea seama despre tine. Procesul de interviu este prima impresie pentru companie. Iar multe incep cu stangul. Poate asa e si aici? Bullet doged ā€¦


(Cosmin Popescu) #9

Offtopic !

Eu am primit ca problema de programare, sa implementez o lista in C asta in conditiile in care postul era de web developer.
Plus operatii pe acea lista

Ontopic
Eu am inteles ca acel script trebuie sa ruleze in linia de comanda, precum o comanda de linux unde ii dai parametrii

Ca o impresie despre acea firma
El a primit problema de back end pt o pozitie de frontend. Nu m-as duce la firme care nu prea stiu ce cer de la un candidat. Am facut o data greseala asta si nu doresc sa o mai repet

PS: Cred ca deja op-ul a rezolvat problema :slight_smile:


(George Grigorita) #10

Aceeasi reactie am avut si eu la inceput, ulterior am inteles ca testul asta e un fel de catch all, in ideea ca au mai multe pozitii si in functie de ce teste rezolv si de modul de rezolvare discutam despre unde as fi mai potrivit.

Testul e mai amplu, am avut o saptamana la dispozitie, include o parte de front-end (realizarea unui layout responsive dupa un PSD dat + nav dinamic cu js/jquery), o parte de PHP cu testul din topicul asta plus inca un script care sa interactioneze cu Facebook API (fara sa folosesc cURL) si inca trei intrebari despre detaliat o metodologie / arhitectura (una cu tangente spre MySQL, una spre dev ops si una spre front-end).

Chiar daca si pentru mine tipul asta de ā€œinterviuā€ e un red flag, am zis sa continui pentru experienta, in ultimii 3 ani n-am mai fost la niciun interviu si din pacate e momentul sa caut altceva.

Multumesc tuturor pentru ajutor si sugestii, dupa cum a zis si tekkie, am facut scriptul cu getopt. Am folosit libraria GD pentru ca e deja integrata in PHP. Pun scriptul mai jos:

#!/usr/bin/env php
<?php
function request(array $options = []) {

    $defaults = [
        'path' => '',
        'width' => '',
        'height' => '',
        'name' => ''
    ];
    $options += $defaults;

    $args = getopt('', ['path:', 'name:', 'width::', 'height::',]) + $options;
    
    $path = $args[path];
    $filename = $args[name];
    $new_width = (int) $args[width];
    $new_height = (int) $args[height];

    return resizeImage($path, $filename, $new_width, $new_height);
}

function resizeImage($path, $filename, $new_width, $new_height) {

    if (check_path($path)) {
        list($width, $height) = getimagesize($path);
    }
    
    if ($new_width === 0) {
        $new_width = $width;

        if ($width < $height && $new_width < $width) {
            $new_width = $width / ($height / $new_height);   
        }
    }
    
    if ($new_height === 0) {
        $new_height = $height;

        if ($width > $height && $new_height < $height) {
            $new_height = $height / ($width / $new_width);
        }
    }

    $thumb = imagecreatetruecolor($new_width, $new_height);
    
    $source = imagecreatefromjpeg($path);

    imagecopyresized($thumb, $source, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
    
    if (!empty($filename)) {
        imagejpeg($thumb, $filename, 100); 
    } else {
        print "Filename cannot be empty.\n";
        exit();
    }
    
    return print "New image $filename was created succesfully in $path.\nThe image size is $new_width x $new_height px.\n";
}

function check_path($path) {
    if ((file_exists($path)) && (exif_imagetype($path) === IMAGETYPE_JPEG)) {
        return true;
    } else {
        print "Error: not a jpg image or invalid path.\nWorks only with jpg images.\nAvailable options are: --path, --filename, --width and --height.\nPath and filename are required.\n";
        exit();
    }
}

request();
?>

(Cosmin Popescu) #11

Felicitari :slight_smile:

Succes !
Imi place abordarea din script !
Este prima data cand am folosit getopt();

Asta cu teste ce cuprinde mai multe lucruri si in functie de ce faci la el, am mai intalnit-o si eu


(Cosmin Popescu) #12

cu file_get_contents() ?