PHP ve HTML

PHP ve HTML etkileşir: PHP, HTML üretir; HTML, PHP'ye bilgi aktarır. Bu SSS'yi okumaya başlamadan önce değişkenlerin dış kaynaklardan nasıl elde edildiğini öğrenmiş olmanız önemlidir. Bu konu ile igili kılavuz sayfası ayrıca örnekler de içerir.

Bir değeri bir form veya URL üzerinden aktarırken nasıl kodlamak gerekir?

Hangi kodlamanın hangi aşamada kullanılacağı önemlidir. İçeriğini kodlamaksızın aktarmak istediğiniz string türünde $data diye bir değişkeniniz olduğunu varsayalım. Aşamalar şunlardır:

  • HTML yorumlaması. Rasgele bir dizgeyi belirtirken dizgeyi çift tırnak içine almanız ve değerin tamamına htmlspecialchars() uygulamanız gerekir.

  • URL: Bir URL çeşitli parçalardan oluşur. Verinizin tek bir öğe olarak yorumlanmasını isterseniz, veriyi urlencode() ile kodlamanız gerekir.

Örnek 1 - Gizli bir HTML form elemanı

<?php
    
echo '<input type="hidden" value="' htmlspecialchars($data) . '" />'."\n";
?>

Bilginize: $data için urlencode() kullanmak yanlıştır, çünkü veriyi urlencode() türünde kodlamak tarayıcının sorumluluğundadır. Bunun yöntemden (yani GET veya POST) bağımsız oluşuna dikkat ediniz. Bunu sadece GET isteklerinde farkedersiniz, çünkü POST istekleri normalde gizlidir.

Örnek 2 - Kullanıcı tarafından düzenlenen veri

<?php
    
echo "<textarea name='mydata'>\n";
    echo 
htmlspecialchars($data)."\n";
    echo 
"</textarea>";
?>

Bilginize: Umulduğu gibi veri tarayıcıda gösterilir, çünkü HTML öncelemeli simgeleri tarayıcının yorumlaması gerekir. Verinin GET veya POST üzerinden gönderiminde veri aktarılırken tarayıcı tarafından kodlanır (urlencode) ve bu kodlama PHP tarafından çözülür (urldecode). Böylece, sizin kodlamayla ilgili birşeyler yapmanız gerekmez, herşey özdevinimli olarak gerçekleşir.

Örnek 3 - Bir URL içinde

<?php
    
echo '<a href="' htmlspecialchars("/nextpage.php?stage=23&data=" .
        
urlencode($data)) . '">'."\n";
?>

Bilginize: Aslında bir HTML GET isteğini taklit ettiğinizden veriye urlencode() uygulamanız gerekmez.

Bilginize: URL, bir HTML özniteliğinin değeri olduğundan URL'nin tümüne htmlspecialchars() kodlaması uygulamanız gerekir. Bu durumda, tarayıcı değere htmlspecialchars() çözümlemesi uyguladıktan sonra URL olarak aktarır. PHP, URL'yi doğru olarak algılayacaktır, çünkü veriye urlencode() uygulamışsınızdır. URL'deki & yerine &amp; yazıldığını farkedeceksiniz. Çoğu tarayıcı bunu sizin yerinize yaptığından bunu yapmayı unutsanız da o kadar önemli değildir. Ancak, URL'niz devingen olmasa bile, URL'ye htmlspecialchars() uygulamanız gerekir.

Bir <input type="image"> etiketi kullanmayı deniyorum, ama $foo.x ve $foo.y değişkenlerini bulamıyorum. $_GET['foo.x'] mevcut değil mi? Bunlar neredeler?

Bir formu göndermek için bir gönderi düğmesi yerine aşağıdaki gibi bir resim kullanmak da mümkündür:

<input type="image" src="dugme.gif" name="foo" />
Kullanıcı bu resmin herhangi bir yerine tıkladığında sunucuya formla birlikte ek olarak foo.x ve foo.y diye iki değişken aktarılır.

foo.x ve foo.y PHP'de geçersiz değişken isimleri olduklarından sihirli bir şekilde bunlar foo_x ve foo_y değişkenlerine dönüşürler. Yani, nokta imi yerine altçizgi imi yerleştirilir. Dolayısıyla, bu değişkenlere dış kaynaklı değişkenler bölümünde açıkladığı gibi erişebilirsiniz. Örnek: $_GET['foo_x'].

Bilginize:

İstekle aktarılan değişken isimlerindeki boşluklar da alçizgi imleri ile değiştirilir.

Bir HTML <form>'unda dizileri nasıl oluşturabilirim?

<form> sonucunu bir dizi olarak göndermek için PHP betğinizde <input>, <select> veya <textarea> elemanlarını şöyle isimlendirmeniz gerekir:

<input name="Dizim[]" />
<input name="Dizim[]" />
<input name="Dizim[]" />
<input name="Dizim[]" />
Değişken isimlerinden sonra gelen köşeli ayraçları farketmişsinizdir. Bunlar değişkeni bir dizi haline getirirler. Farklı elemanlara aynı dizi isimlerini atamak suretiyle elemanları farklı diziler içinde gruplayabilirsiniz:
<input name="Dizim[]" />
<input name="Dizim[]" />
<input name="ÖbürDizim[]" />
<input name="ÖbürDizim[]" />
Bu örnekte PHP betiğine gönderilmek üzere iki dizi üretilmektedir: Dizim ve ÖbürDizim. Dizilerinize ayrıca özel anahtarlar atamanız da mümkündür:
<input name="DiğerDizim[]" />
<input name="DiğerDizim[]" />
<input name="DiğerDizim[eposta]" />
<input name="DiğerDizim[telefon]" />
Burada, DiğerDizim dizisi 0, 1, eposta ve telefon anahtarlarını içerecektir.

Bilginize:

HTML'de dizi anahtarlarını belirtmek isteğe bağlıdır. Anahtar belirtmezseniz, dizi elemanları formda yer alış sırasına göre numaralanır. Örneğimizde anahtarlar 0, 1, 2 ve 3 olacaktır.

Ayrıca bakınız: Dizi İşlevleri ve Dış Kaynaklı Değişkenler .

Çok HTML etiketli bir select etiketinden tüm sonuçları nasıl alırım?

Bir HTML'deki çok seçenekli bir select oluşumu kullanıcıların bir listeden çok sayıda öğe seçebilmesini mümkün kılar. Seçilen öğeler form için atanmış bir eylemciye aktarılırlar. Burada sorun, hepsinin aynı değişken ismiyle aktarılmasıdır. Örnek:

<select name="var" multiple="yes">
Seçilen her seçenek eylemciye şöyle aktarılacaktır:
var=seçim1
var=seçim2
var=seçim3
      
Her seçenek bir önceki $var değişkeninin içeriğinin üzerine yazacaktır. Çözüm, değişken ismi olarak dizi kullanmaktır:
<select name="var[]" multiple="yes">
Bu satır PHP'ye $var değişkenini bir dizi olarak ele almasını ve her seçeneğin içeriği için bir dizi elemanı eklemesini söyler. İlk seçim $var[0], ikincisi $var[1], vs. olur. Kaç seçeneğin seçilmiş olduğunu count() işlevi ile öğrenebilir veya gerekirse sort() işleviyle seçenek dizisini sıraya sokabilirsiniz.

JavaScript kullanıyorsanız eleman ismindeki [] ayraçları, elemanlara isimleriyle başvururken sorun çıkarabilir. Ya eleman anahtarı yerine sayısal biçimi kullanın ya da değişken isimlerini tek tırnak içine alıp bunları dizi elemanlarını indislemekte kullanın. Örnek:

variable = document.forms[0].elements['var[]'];
      

Bir değişkeni Javascript'ten PHP'ye nasıl aktarabilirim?

Javascript'in (normal olarak) istemci taraflı, PHP'nin sunucu taraflı olması ve HTTP'nin de 'durumsuz' bir protokol olması nedeniyle iki dil değişkenleri doğrudan paylaşamazlar.

Bununla birlikte, ikisi arasında değişken alışverişi mümkündür. Bunu sağlamanın tek yolu Javascript kodunu PHP ile üretmek ve tarayıcıya tazeletip özel değişkenleri gerisin geriye PHP'ye aktarmaktır. Aşağıdaki örnekte bunun nasıl yapıldığı ayrıntılı olarak gösterilmiştir. Normalde sadece istemci tarafında mümkün olan ekran yüksekliği ve genişliğinin elde edilmesi PHP kodunda gerçeklenmektedir.

Örnek 4 - PHP ile Javascript üretimi

<?php
if (isset($_GET['width']) AND isset($_GET['height'])) {
  
// Boyut değişkenlerini çıktılayalım
  
echo "Ekran genişliği: "$_GET['width'] ."<br />\n";
  echo 
"Ekran yüksekliği: "$_GET['height'] ."<br />\n";
} else {
  
// Boyut değişkenlerini aktaralım
  // (özgün sorgu dizgesini koruyalım
  //   -- post değişkenleri farklı şekilde elde edilecek)

  
echo "<script language='javascript'>\n";
  echo 
"  location.href=\"${_SERVER['SCRIPT_NAME']}?${_SERVER['QUERY_STRING']}"
            
"&width=\" + screen.width + \"&height=\" + screen.height;\n";
  echo 
"</script>\n";
  exit();
}
?>

add a note add a note

User Contributed Notes 11 notes

up
3
martellare at hotmail dot com
14 years ago
I do not think you are right about not being able to specify something for the value attribute, but I can see where you would have thought it would fail:

A fair warning about testing to see if a variable exists...
when it comes to strings, the values '' and '0' are interpreted as false when tested this way...

<?php
if ($string) { ... }  //false for $string == '' || $string == '0'
?>

The best practice for testing to see if you received a variable from the form (which in the case of a checkbox, only happens when it is checked) is to test using this...

<?php
if ( isSet($string) ) { ... } //true if and only if the variable is set
?>

The function tests to see if the variable has been set, regardless of its contents.

By the way, if anyone's curious, when you do make a checkbox without specifying the value attribute, the value sent from the form for that checkbox becomes 'on'.  (That's for HTML in general, not PHP-specific).
up
-5
jetboy
11 years ago
While previous notes stating that square brackets in the name attribute are valid in HTML 4 are correct, according to this:

http://www.w3.org/TR/xhtml1/#C_8

the type of the name attribute has been changed in XHTML 1.0, meaning that square brackets in XHTML's name attribute are not valid.

Regardless, at the time of writing, the W3C's validator doesn't pick this up on a XHTML document.
up
-5
martellare at hotmail dot com
14 years ago
A JavaScript Note: Using element indexes to reference form elements can cause problems when you want to add new elements to your form; it can shift the indexes of the elements that are already there.

For example, You've got an array of checkboxes that exist at the beginning of a form:
===================

<FORM>
    <INPUT type="checkbox" name="fruits[]" value="apple">apple
    <INPUT type="checkbox" name="fruits[]" value="orange">orange
    <INPUT type="checkbox" name="fruits[]" value="banana">banana
</FORM>

===================
... These elements could be referenced in JavaScript like so:
===================

<SCRIPT language="JavaScript" type="text/javascript">
<!--
    var index = 0; //could be 1 or 2 as well
    alert(document.forms[0].elements[index]);
//-->
</SCRIPT>

===================
However, if you added a new textbox before these elements, the checkboxes indexes become 1 - 3 instead of 0 - 2;  That can mess up what ever code you create depending on those indexes.

Instead, try referencing your html arrays in JavaScript this way.  I know it works in Netscape 4 & IE 6, I hope it to some extent is universal...
===================

<SCRIPT language="JavaScript" type="text/javascript">
<!--
    var message = "";
    for (var i = 0; i < document.forms[0].elements['fruits[]'].length; i++)
    {
        message += "events[" + i + "]: " + document.forms[0].elements['fruits[]'][i].value + "\n";
    }
    alert(message);
//-->
</SCRIPT>

===================
up
-11
davis at risingtiger dot net
13 years ago
I thought this might be useful to fellow PHP heads like myself out there.

I recently came across a need to transfer full fledged mutli-dimensional arrays from PHP to JAVASCRIPT.

So here it is and hopefuly good things come from it.

<?php
function phparray_jscript($array, $jsarray)
{
    function
loop_through($array,$dimen,$localarray)
    {
        foreach(
$array as $key => $value)
        {
            if(
is_array($value))
            {
                echo (
$localarray.$dimen."[\"$key\"] = new Array();\n");
               
loop_through($value,($dimen."[\"".$key."\"]"),$localarray);
            }
            else
            {
                echo (
$localarray.$dimen."[\"$key\"] = \"$value\";\n");
            }
        }
    }

    echo
"<script language=\"Javascript1.1\">\n";
    echo
"var $jsarray = new Array();\n";
   
loop_through($array,"",$jsarray);
    echo
"</script>";
}
?>
up
-12
Jay
3 years ago
If you have a really large form, be sure to check your max_input_vars setting.  Your array[] will get truncated if it exceeds this.  http://www.php.net/manual/en/info.configuration.php#ini.max-input-vars
up
-14
francesco
10 years ago
Another way to pass variables from JavaScript to PHP.

<script type="text/javascript" language="JavaScript">
<!--
function getScreenResolution()
{
    return document.form.ScreenResolution.value = screen.width + "x" + screen.height;
}
//-->
</script>
<form name="form" action="screen.php?show=ok" method="post" >
<input name="ScreenResolution" type="text" size="20" maxlength="9" />
<input name="show" type="submit" value="Submit" onclick="getScreenResolution()" />
</form>
<?php
   
echo $_POST['ScreenResolution'];
?>
up
-16
tchibolecafe at freemail dot hu
10 years ago
Notes on question "1. What encoding/decoding do I need when I pass a value through a
form/URL?"

Doing an htmlspecialchars() when echoing a string as an HTML attribute value is not enough to make the string safe if you have accented (non-ASCII) characters in it. See http://www.w3.org/TR/REC-html40/appendix/notes.html#non-ascii-chars

The referred document recommends the following method to be used:

<?php
 
function fs_attr($path){
   
$retval='';
    for(
$i=0;$i<strlen($path);$i++){
     
$c=$path{$i};
      if(
ord($c)<128){
       
$retval.=$c;
      }else{
       
$retval.=urlencode(utf8_encode($c));
      }
    }
    return
htmlspecialchars($retval);
  }

 
$img_path='éöüä.jpg';
  echo
'<img src="'.fs_attr($img_path).'">';
?>

However, using utf8 encoding for path names is among others supported by Windows NT, above method fails when running for example on an Apache server on Linux.

A more fail safe way:

<?php
       
function fs_attr($path){
               
$retval='';
                for(
$i=0;$i<strlen($path);$i++){
                       
$c=$path{$i};
                        if(
ord($c)<128){
                               
$retval.=$c;
                        }else{
                                if(
PHP_OS==='WINNT')
                                       
$retval.=urlencode(utf8_encode($c));
                                else
                                       
$retval.=urlencode($c);
                        }
                }

                return
htmlspecialchars($retval);
        }
?>

There may be operating systems that want utf8 encoding, other than WINNT. Even this latter one won't work on those systems. I don't know about any possibility to determine immediately which encoding to be used on the file system of the server...
up
-17
levinb at cs dot rpi dot edu
11 years ago
Well, I was working on this one project, on the assumption that I could get the values of all elements with the same name from an appropriately named array.  Well, I was *very* disappointed when I couldn't, so I made it so I did anyway.

The following script should convert the raw post data to a $_POST variable, with form data from SELECT elements and their ilk being transformed into an array.  It's heavily unoptimized, and I probably missed something, but it's relatively easy to read.  I welcome corrections.

<?php

if ($_POST) {
       
$postdata = file_get_contents('php://input');
       
       
$uglybugger = '/(?<=&)([^&=]+)(?:=([^&]*))/';
       
$matches = array();

       
preg_match_all($uglybugger, $postdata, $matches);

       
$_POST = array();

       
$match_count = count($matches[0]);
        for (
$i = 0; $i < $match_count; $i++) {
                if (!isset(
$_POST[$matches[1][$i]])) {
                       
$_POST[$matches[1][$i]] = array();
                }
               
$_POST[$matches[1][$i]][] = $matches[2][$i];
        }
       
$match_count = count($_POST);
        for (
$i = 0; $i < $match_count; $i++) {
                if (
count($_POST[$i]) == 1) {
                       
$_POST[$i] = $_POST[$i][0];
                }
        }
}

?>
up
-16
dreptack at op dot pl
12 years ago
I needed to post html form through image input element. But my problem was I had to use multiple image-buttons, each one for a single row of form table. Pressing the button was mention to tell script to delete this row from table and also (in the same request) save other data from the form table.
I wrote simple test-script to see what variable I should check for in a script:

I have a html document:

<form action="test.php" method="post">
<input type="image" name="varscalar" src="/images/no.gif" />
<input type="image" name="vararray[12]" src="/images/no.gif" />
</form>

And a php script:
<?php
 
if ($_POST) {
    echo
"post: <pre>"; print_r($_POST); echo '</pre>';
  }
?>

What I've discovered suprised me a lot!

After hitting on varscalar:

post:
Array
(
    [varscalar_x] => 6
    [varscalar_y] => 7
)

After hitting on upper right corner of vararray:

post:
Array
(
    [vararray] => Array
        (
            [12] => 2
        )

)

This mean when clicking on image-type input element, which name is an array, only y-part of a value is remembered.

The result is the same on: php 4.1.2 on Win98se, php 4.3.9-1 on linux
up
-20
dmsuperman at comcast dot net
11 years ago
Here's a great way to pass JavaScript to PHP without even leaving the page:

<script type="text/javascript">
<!--

function xmlreq(){
  if(window.XMLHttpRequest){
    req = new XMLHttpRequest();
  }else if(window.ActiveXObject){
    req = new ActiveXObject("Microsoft.XMLHTTP");
  }
  return(req);
}
function sendPhp(url){
  var req = xmlreq();
  req.onreadystatechange = stateHandler;
  req.open("GET", url, true);
  req.send(null);
}

sendPhp("updatedatabase.php?username=blah&displayname=whatever");
//-->
</script>
up
-26
Kenn White kennwhite dot nospam at hotmail dot com
13 years ago
Concerning XHTML Strict and array notation in forms, hopefully the information below will be useful:

If I have a form, name="f", and, say, an input text box, name="user_data[Password]", then in Javascript, to reference it I would do something like:
   
var foo = f['user_data[Password]'].value;

Now, say that in making the switch to XHTML strict, I decide to fully embrace standards compliance, and change my form to id="f", and the input text box to id="user_data[Password]"

Because these have id instead of name, I discover, that all my javascript validation routines just broke.  It seems that I have to now change all my js code to something like:

document.getElementById( 'user_data[Password]' ).focus();

I test this on all the major modern browsers, and it works well.  I'm thinking, Great!  Until I try to validate said page.  It turns out that the bracket characters are invalid in id attributes.  Ack!  So I read this thread:

http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=
UTF-8&th=78dea36fd65d9bbe&seekm=
pqx99.19%24006.13377%40news.ca.inter.net#link11
(link needs to be spliced, sorry)

What does this mean, I start asking myself?  Do I have to abandon my goal to migrate to XHTML strict?  Transitional seems so unsatisfying.  And why bother with a technique that seems to work on most browsers, if it's broken.  Alas, there is hope.

But then I read http://www.w3.org/TR/xhtml1/#h-4.10 carefully.  It says "name" is deprecated as a form attribute, but *NOT* specifically as an attribute in form *elements*.  It seems my solution is to use "id" for the form itself, but I can legally use "name" for the individual form components, such as select and text input boxes.  I get the impression that "name" as an attribute is eventually going away completely, but in extensive testing using the W3C validator, it passes "name" on form components, as long as "id" (or, strangely, nothing) is used to denote the form itself.

So for XHTML strict, the bottom line:
1. form, use id, not name
2. input, use id if you can, but if you need to use bracketed notation (for example, passing PHP arrays), i.e., foo[], you *MUST* use name for XHTML strict validation.

-kenn

kennwhite.nospam@hotmail.com
To Top