content top

Intreaba-ma: Executarea de scripturi PHP asincron

Intreaba-ma: Executarea de scripturi PHP asincron

Am fost abordat de unul din cititorii mei cu urmatoarea situatie (am sa reproduc felul in care a pus el problema):

Avem de-a face cu o pagina simpla (un HTML, sa zicem) care contine un formular; o vom numi pagina A. Pagina A face submit catre un script PHP, pe care-l vom numi B si care dupa ce termina ce are de facut redirecteaza utilizatorul catre pagina C (un landing page).

Deci care e problema? Pai, problema e ca scriptul B ruleaza cam mult (trimite o serie de email-uri) si utilizatorul sta si asteapta ca browser-ul sa incarce “ceva”.

Gabriel a venit cu o solutie interesanta la aceasta problema. A cautat un preloader care sa ruleze in timp ce se incarca scriptul B. Nu-i rau, dar eu cred ca aici se preteaza bine un AJAX. In general pentru astfel de situatii executarea asincrona este cea mai buna solutie.

Vezi Demo

Avand in vedere noile informatii, abordarea va fi in felul urmator: Pagina A face un request AJAX catre scriptul B si asteapta un raspuns. Intre timp afisaza o imagine de loading… (sau orice altceva). Cand termina ce are de facut, scriptul B il anunta pe A ca este momentul sa faca un redirect; catre landing page-ul C.

Bun, acum ca am vauzut despre ce-i vorba, sa descuram putin itele problemei. Vom incepe prin a da nume descriptive fisierelor, ca sa nu ne mai incurcam in litere.

Fisierul care contine formularul se numeste index.php si contine urmatorul cod:

<!DOCTYPE html>
<html lang="en">

<head>
	<title>AJAX Submitter</title>
	<link rel="stylesheet" href="style.css" type="text/css" />
</head>

<body>

	<div id="wrapper">
		<form method="POST" action="submit.php">
			<p>
				<label for="name">Name</label>
				<input type="text" name="name" id="name" />
			</p>
			<p>
				<label for="email">Email</label>
				<input type="text" name="email" id="email" />
			</p>
			<p>
				<label for="message">Message</label><br />
				<textarea name="message" cols="50" rows="7"></textarea>
			</p>
			<p>
				<input type="submit" value="Send" id="submit" />
				<img id="spinner" src="loading.gif" style="display:none; float: right;" />
			</p>
		</form>
	</div>

</body>

</html>

Codul este cat se poate de simplu, ca sa nu pierdem din vedere scopul principal. Dupa cum vedeti, formularul face submit catre un fisier PHP numit sugestiv submit.php.

<?php

session_start();

$name = "No name sumbitted";
if(isset($_POST["name"]))
	$name = $_POST["name"];

$email = "No email sumbitted";
if(isset($_POST["email"]))
	$email = $_POST["email"];

$message = "No message sumbitted";
if(isset($_POST["message"]))
	$message = $_POST["message"];

$_SESSION["name"] = $name;
sleep(3);
$_SESSION["email"] = $email;
sleep(3);
$_SESSION["message"] = $message;
sleep(3);

header("Location: landing.php");

?>

Codul este irelevant. L-am pus acolo doar ca sa execute ceva in spate. Mai mult, observati folosirea functiei sleep() de cateva ori. Asta ca sa simuleze faptul ca scriptul dureaza ceva mai mult decat in mod normal.

Dupa ce se executa codul, trimitem utilizatorul la un landing.php ca sa-l anuntam ca totul s-a intamplat cu succes. Codul arata asa:

<?php session_start(); ?>
<!DOCTYPE html>
<html lang="en">

<head>
	<title>AJAX Landing</title>
	<link rel="stylesheet" href="style.css" type="text/css" />
</head>

<body>

	<div id="wrapper">
		<h3>The following data has been sumbitted</h3>
		<p>Name: <?php echo $_SESSION["name"] ?></p>
		<p>Email: <?php echo $_SESSION["email"] ?></p>
		<p>Message: <?php echo $_SESSION["message"] ?></p>
	</div>

</body>

</html>

In momentul de fata avem exact situatia despre care vorbeam mai sus. La click, user-ul este trimis la submit.php unde nu vede decat o fereastra goala pana se executa codul. Abia la final este trimis catre landing.php.

Ca sa rezolvam problema, vom executa scriptul submit.php asincron. Ca sa ne fie mai usor, vom apela la jQuery pentru partea de AJAX.

Mai intai includem libraria jQuery:

	<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>

Apoi, tot ce trebuie sa facem este sa adaugam cateva linii de cod. Explicatiile le gasiti in comentarii la fiecare linie de cod unde acest lucru este necesar. P.S. Daca vi se pare greu de citit, il aveti mai jos fara comentarii (plus arhiva de la final):

	$(document).ready(function() {
		$("#submit").click(function(event) { // Declansam la click pe Submit
			event.preventDefault(); // Avem grija sa nu mai faca submit clasic
			$.ajax({
				url: "submit.php", // Unde facem requestul AJAX
				beforeSend: function() { // Inainte de request executam:
					$("#submit").css("display", "none"); // Ascundem butonul de submit
					$("#spinner").css("display", "block"); // Incarcam un loader (un gif)
				},
				type: "POST",
				data: ({
							name: $("#name").val(), // Luam valoarea lui 'name' pentru submit
							email: $("#email").val(), // Luam valoarea lui 'email' pentru submit
							message: $("#message").val() // Luam valoarea lui 'message' pentru submit
				}),
				success: function(msg) {
					window.location.replace("landing.php"); // La final, redirectam utilizatorul la landing.php
				}
			});
		});
	});

La final, ar trebui sa obtinem un fisier index.php care arata asa:

<!DOCTYPE html>
<html lang="en">

<head>
	<title>AJAX Submitter</title>
	<link rel="stylesheet" href="style.css" type="text/css" />
	<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
	<script type="text/javascript">
		$(document).ready(function() {
			$("#submit").click(function(event) {
				event.preventDefault();
				$.ajax({
					url: "submit.php",
					beforeSend: function() {
						$("#submit").css("display", "none");
						$("#spinner").css("display", "block");
					},
					type: "POST",
					data: ({
							name: $("#name").val(),
							email: $("#email").val(),
							message: $("#message").val()
					}),
					success: function(msg) {
						window.location.replace("landing.php");
					}
				});
			});
		});
	</script>
</head>

<body>

	<div id="wrapper">
		<form method="POST" action="submit.php">
			<p>
				<label for="name">Name</label>
				<input type="text" name="name" id="name" />
			</p>
			<p>
				<label for="email">Email</label>
				<input type="text" name="email" id="email" />
			</p>
			<p>
				<label for="message">Message</label><br />
				<textarea name="message" cols="50" rows="7"></textarea>
			</p>
			<p>
				<input type="submit" value="Send" id="submit" />
				<img id="spinner" src="loading.gif" style="display:none; float: right;" />
			</p>
		</form>
	</div>

</body>

</html>

Dupa cum vedeti, n-am schimbat nimic in fisierele submit.php si landing.php. Am schimbat numai modul in care apelam aceste fisiere.

Acestea sunt elementele de baza pe care trebuie sa le stim pentru a oferi utilizatorului o experienta mai eleganta cu ajutorul AJAX.

Descarca arhiva

Read More

Adobe Romania angajeaza Graphic Designer

Adobe Romania angajeaza Graphic Designer

Se pare ca Adobe Romania angajeaza. Nimic nou pana aici, dar inca nu v-am spus pe ce post. Pentru prima data, conform spuselor lor, Adobe Romania cauta un Graphic Designer pentru echipa Business Catalyst.

Din ce am inteles, postul presupune atat Web Design cat si grafica pentru mediul digital si print. Veti beneficia de cele mai noi  unelte de design (ar fi cazul, sunt in-house) pentru a va putea desfasura activitatea cat mai bine.

Eu sunt un biet programator fara niciun pic de simt creativ sau estetic, dar cei dintre voi care “viseaza in layers”, asa cum spun cei de la Adobe Romania, poate ar fi bine sa-si incerce norocul si abilitatile.

Read More

Conditii in ColdFusion – tag-urile cfif/cfelse

Conditii in ColdFusion – tag-urile cfif/cfelse

In acest articol vom trata un subiect aparent banal printre programatori. Si cand spun banal, nu inseamna ca este mai putin important. Numai ca fiind folosit atat de des, acest element sa trivializeaza si-l luam ca pe un dat.

Este vorba despre banalele expresii conditionale. Am ales sa dedic un articol acestui element dintr-un motiv foarte simplu. Asa cum va spuneam si intr-un articol anterior, ColdFusion abordeaza putin diferit unele lucruri.

Expresiile if/else sunt un exemplu bun al acestui lucru.

Ca sa intelegem mai bine, sa vedem cateva bucati de cod. In PHP (ca in majoritatea limbajelor de altfel), un bloc if/else ar arata asa:

<?php
if($condition === true)
{
	// executa cod
}
else
{
	// executa cod
}
?>

Dar sa nu ne cramponam de limbaj. Hai sa vedem un bloc de cod generalizat, ca sa-l comparam dupa aceea cu ColdFusion.

if(expresie_de_evaluat)
{
	executa cod
}
else
{
	executa cod
}

Bun, din cele doua blocuri de cod, se vede destul de clar cum arata expresia if/else. Haideti sa portam acest cod in ColdFusion sa vedem cu ar arata. Studiind blocul de mai sus, am fi tentati sa scriem ceva de genul acesta:

<cfif expresie_de_evaluat>
	<!--- executa cod --->
</cfif>
<cfelse>
	<!--- executa cod --->
</cfelse>

Deci, ce nu e bine aici? Avem un bloc if, iar cand acesta se finalizeaza incepe blocul else. Ei bine, ColdFusion vede blocul if/else in felul urmator:

<cfif expresie_de_evaluat>
	<!--- executa cod --->

	<cfelse>
		<!--- executa cod --->
</cfif>

Dupa cum vedeti, <cfif> este singurul care se inchide. Totul se intampla in interiorul acestui tag, ramanand ca <cfelse> sa fie inclus tot aici. Obeservati de asemenea, ca <cfelse> nu se inchide. El tine automat din locul in care este deschis, pana acolo unde se termina <cfif>.

Si pentru cei dintre voi care sunteti fani ai lui elseif, tin sa va spun ca si ColdFusion ofera asa ceva. Se numeste <cfelseif> si se foloseste asa:

<cfif expresie_de_evaluat>
	<!--- executa cod --->

	<cfelseif expresie2_de_evaluat>
		<!--- executa cod --->

	<cfelse>
		<!--- executa cod --->
</cfif>

Dupa cum vedeti, conditiile nu sunt nici pe departe mai grele in ColdFusion. Sunt doar putin diferite fata de cele cu care ne-am obisnuit. Happy Coding.

Read More

Operatorul de egalitate in ColdFusion

Operatorul de egalitate in ColdFusion

As vrea sa vorbim in acest articol, despre operatorul de egalitate din ColdFusion. Fiind mai degraba un meta-limbaj, ColdFusion a implementat unele lucruri putin diferit fata de alte limbaje web cu care ne-am obisnuit.

Este si cazul operatorului egal. Acesta arata total diferit in contextul de comparare fata de cel de asignare. Derutant? Da, stiu, e mai greu de exprimat in cuvinte. Hai sa vedem niste exemple ca sa intelegem mai bine despre ce este vorba.

In PHP, asignarea se face cu un singur egal, iar compararea sa face cu 2 (==) sau 3 (===) egal, dupa caz. Un exemplu simplu ar arata asa:

<?php

$value = 2; // asignare

if($value == 2) // comparare
{
	echo "Valoarea este doi";
}
else
{
	echo "Valoarea este diferita de doi";
}

?>

In ColdFusion insa, operatorii arata altfel. Sa vedem cum arata codul:

<cfset value = 2 /> <!--- asignare --->
<cfif value eq 2> <!--- comparare --->
	<cfoutput>Valoarea este doi</cfoutput>
	<cfelse>
		<cfoutput>Valoarea este diferita de doi</cfoutput>
</cfif>

Dupa cum observati, ColdFusion evita folosirea lui dublu si triplu egal. Nu stiu daca este din dorinta de a evita confuzia, sau vreo mostenire din Java (?), dar pentru comparare ColdFusion foloseste operatorul eq.

Pe de alta parte, mai exista o logica in spatele acestei alegeri. Trebuie sa tinem minte ca avem de-a face cu un limbaj de programare pe baza de tag-uri. Mai mult, trebuie sa tinem cont ca “egal” nu este singurul operator de comparare. Mai exista “mai mare”, “mai mic” etc.

Avand in vedere acest lucru, sa ne gandim ce-ar insemna folosirea acestor operatori in forma clasica. Codul ar arata asa:

<cfif value > 2>
	<cfoutput>Valoarea este mai mare decat doi</cfoutput>
	<cfelse>
		<cfoutput>Valoarea nu este mai mare decat doi</cfoutput>
</cfif>

<cfif value < 2>
	<cfoutput>Valoarea este mai mica decat doi</cfoutput>
	<cfelse>
		<cfoutput>Valoarea nu este mai mica decat doi</cfoutput>
</cfif>

Se poate vedea foarte clar ca acest cod nu va functiona niciodata. Nu poti avea < sau > in interiorul unui tag care se bazeaza pe aceste caractere rezervate pentru a construi structura codului. Asa ca cei doi vor trebui inlocuiti astfel:

<cfif value gt 2>
	<cfoutput>Valoarea este mai mare decat doi</cfoutput>
	<cfelse>
		<cfoutput>Valoarea nu este mai mare decat doi</cfoutput>
</cfif>

<cfif value lt 2>
	<cfoutput>Valoarea este mai mica decat doi</cfoutput>
	<cfelse>
		<cfoutput>Valoarea nu este mai mica decat doi</cfoutput>
</cfif>

Si daca am inlocuit < si > cu lt si gt, ar fi aberant sa facem nota discordanta la =. Nimic nu e mai rau decat un limbaj de programare inconsecvent. Prin urmare < devine lt, > devine gt, iar = devine eq.

Aceasta a fost mica noastra incursiune in operatorii din ColdFusion. Voi reveni cu alte articole despre lucruri pe care ColdFusion le trateaza putin diferit de alte limbaje.

Read More

Tipuri de variabile in PHP

Tipuri de variabile in PHP

Vom vorbi in acest articol despre un aspect de care programatorii PHP tin cont destul de rar: tipul variabilei cu care lucreaza. Este adevarat ca PHP nu este foarte pretentios din acest punct de vedere, asa ca de ce ne-am bate capul cu asa ceva?

Pai, depinde foarte mult de situatiile in care ne gasim. Sa zicem ca avem de-a face cu un API care intoarce printre altele TRUE si FALSE. Ati crede ca sunt valori de tip BOOLEAN dar nu este mereu asa. Am avut de-a face cu astfel de interfete care desi intorceau success => TRUE nu era o valoarea booleana, ci sirul de caractere “TRUE”.

Mi-a luat ceva timp sa-mi dau seama ce se intampla de fapt, pentru ca daca printezi valoarea la ecran, vezi doar TRUE, ceea ce poate sa insemne orice. Asa ca am cautat putin si am descoperit ca exista o functie foarte utila in PHP. Se numeste gettype() si intoarce tipul variabilei evaluate.

Sa vedem o bucata de cod care sa exemplifice ceea ce spun:

<?php
$var_string = "5";
$var_int = 5;

$first_eval = gettype($var_string);
$second_eval = gettype($var_int);

echo $first_eval; // rezultat: 'string'
echo $second_eval; // rezultat: 'integer'
?>

De asemenea, pentru cei carora le place sa specifice tipul variabilelor cu care lucreaza (daca au background de Java sau AS3 de exemplu) exista si un settype(). Acesta ia doi parametri: primul este variabila pe care vrem sa o setam si al doi-lea este tipul pe care dorim sa-l “imprimam”.

<?php
settype($var_string, "integer");
$eval = gettype($var_string);

echo $eval; // rezultat: 'integer'
?>

* Observati ca nu am mai definit variabile $var_string. Asta pentru ca am folosit-o pe cea din exemplul de mai sus.

Atentie, functia settype() nu intoarce variabila setata. Nu fiti tentati sa scrieti codul in felul urmator:

<?php
$new_var = settype($var_string, "integer");
$eval = gettype($new_var);

echo $eval; // rezultat: 'boolean'
?>

Codul scris in acest fel va intoarce boolean in loc de integer pentru ca functia settype() intoarce TRUE atunci cand setarea se face cu succes si FALSE cand nu.

Read More
content top
  • RSS
  • Twitter
  • Tumblr
  • Facebook