PHP « Как должен выглядеть php смешанный с javascript

всем привет, написал код удобный но по мой му длинный очень!
помогите пожалуста сделать его правильно.
<?PHP if ($_GET["item"]=="create"):
      $minfo=mysql_fetch_array(mysql_query_sum("SELECT referer FROM users WHERE username='".mysql_real_escape_string($_SESSION[username])."'"));
  if (isset($_POST['submit'])) { $err     = array();
                               $title   = limpiar($_POST["title"]);
                               $message = limpiar($_POST["message"]);
  if ($_POST["user_aprove"]==="user_ok") { $whom = limpiar($_POST["login"]); $_SESSION["mail_to"]="user_to";
     $query=mysql_query("SELECT COUNT(id) FROM abuses WHERE user='".mysql_real_escape_string($_SESSION[username])."' AND cat='mails'")or die ("<br>Invalid query: " . mysql_error());
     if(mysql_result($query, 0) > 3) { $err[] = $lang['vmail_cr_err_1']; } else {
     if(trim($whom)=="") { $err[] = $lang['vmail_cr_err_2']; }
else { $res=mysql_query("select count(*) as kolvo from users WHERE username='".mysql_real_escape_string($whom)."'");
       $res=mysql_fetch_array($res);
       if($res["kolvo"]<1) { $err[] = $lang['vmail_cr_err_3']; }
       if(strtolower($whom)==strtolower($_SESSION[username])) { $err[] = $lang['vmail_cr_err_4']; } } } }

else if($_POST["admin_aprove"]==="admin_ok")  {  $_SESSION["mail_to"]="admin_to";
     $result=mysql_query(" SELECT username,user_rights FROM `users` WHERE user_rights='admin' LIMIT 1 " );
     $admin_rows=mysql_num_rows($result);
     if($admin_rows<1) { $err[] = "administratori nu exista"; }
     else { $res=mysql_fetch_array($result); $whom=$res["username"]; } }

else if($_POST["refer_aprove"]==="refer_ok") { $whom=$minfo["referer"]; $_SESSION["mail_to"]="refer_to"; }
  if (trim($title)=="")                                                 { $err[] = $lang['vmail_cr_err_5']; }  
else { if(strlen($title) < 3 or strlen($title) > 40)                    { $err[] = $lang['vmail_cr_err_6']; } }
  if (trim($message)=="")                                               { $err[] = $lang['vmail_err_6']; }  
else { if(strlen($message) < 10 or strlen($message) > 300)              { $err[] = $lang['vmail_err_3']; } }
  if (md5(strtolower($_POST['code']))!= strtolower($_SESSION['texto'])) { $err[] = $base_err[2];  }
  if (count($err) == 0) { unset($_SESSION["texto"]);
$sql="INSERT INTO mails (de_la,whom,title,message,date,type)VALUES('".mysql_real_escape_string($_SESSION[username])."','$whom','$title','$message',NOW(),'send')"; mysql_query($sql) or die(mysql_error());
echo "<div class=\"okay\">".$lang['vmail_reply_ok']."</div>"; } } ?>

<table width='100%' border='0' cellpadding='0' cellspacing='0' style='margin: 20px 0;'>
 <tr><td align="center" width="33%"><span class="corr1" onclick="javascript:AdminClick();"><b>Àäìèíèñòðàöèÿ</b><br /><?=$site_name?></span></td>
     <td align="center" width="33%">
<?PHP if($minfo["referer"]!="") { ?><span class="corr2" onclick='javascript:RefClick();'><b>Ìîé ðåôåðåð</b><br /><?=$minfo["referer"]?></span>
<? }else{ ?><span class="corr2"><b>Ìîé ðåôåðåð</b><br />Ó âàñ íåòó ðåôåðåðà</span><?PHP } ?>                                </td>
     <td align="center" width="33%"><span class="corr3" onclick="javascript:UserClick();"><b>Ïîëüçîâàòåëü</b><br /><?=$site_name?></span></td>
 </tr>
</table>
<?php if(count($err)>0) { echo "<div class='error'>".$base_err[4]; foreach($err AS $error) { echo "<li>".$error."</li>"; } echo "</div>"; } ?>

    <form name="mailform" method="post" action="">
          <div class="table" style="border-top:1px solid #ba4c32;">
            <table width="100%" border="0" cellspacing="0" cellpadding="0">
              <tr><td width='40%' align="right"><b>Ïîëó÷àòåëü</b></td>
                  <td id="user"><input type='text' name='login' maxlength='10' size="30" value="<?=$whom;?>" />
                   <div style="display: none;"><input type="checkbox" id="user_check" name="user_aprove" value="user_ok" checked="checked" /></div></td>
                  <td id="admin" style="display: none;font-weight:bold;">Àäìèíèñòðàöèÿ FinBUX.info<div style="display: none;"><input type="checkbox" id="admin_check" name="admin_aprove" value="admin_ok" /></div></td>
                  <td id="refer" style="display: none;font-weight:bold;">Ìîé ðåôåðåð <u><?=$minfo["referer"]?><div style="display: none;"><input type="checkbox" id="refer_check" name="refer_aprove" value="refer_ok" /></div></td></tr>                    
              <tr><td align="right">Òåìà ïèñüìà</td>
                  <td><input type="text" name="title" maxlength="40" size="60" value="<?=$title;?>" /></td></tr>
              <tr><td align="right">Ñîäåðæàíèå ïèñüìà<br /><input class="scount" type="text" name="scount" value="Îñòàëîñü 300 ñèìâîëîâ" readonly="readonly" /></td>
                  <td><textarea cols="60" rows="3" name='message' onkeyup="descchange(this);"><?=$message;?></textarea></td></tr>
              <tr><td colspan="2" align="center"><?=$lang['CAPTCHA_ITEM']?>
                   <table border="0" cellpadding="0" cellspacing="1">
                     <tbody><tr><td><img src="image.php?<?php echo $res; ?>" class="imgcap" alt="" /></td>
                                <td><input type="hidden" name="code" value="0">
                                    <input name="submit" value="1" onclick="vernum(this.form,1); submit();" type="submit">
                                    <input name="submit" value="2" onclick="vernum(this.form,2); submit();" type="submit">
                                    <input name="submit" value="3" onclick="vernum(this.form,3); submit();" type="submit">
                                    <input name="submit" value="4" onclick="vernum(this.form,4); submit();" type="submit"><br />
                                    <input name="submit" value="5" onclick="vernum(this.form,5); submit();" type="submit">
                                    <input name="submit" value="6" onclick="vernum(this.form,6); submit();" type="submit">
                                    <input name="submit" value="7" onclick="vernum(this.form,7); submit();" type="submit">
                                    <input name="submit" value="8" onclick="vernum(this.form,8); submit();" type="submit"></td>
              </tr></tbody></table></td></tr>
            </table> </div>
    </form>


<?php endif;

1 ответов


Начав вглядываться в код дальше пяти строк, я заметил что у вас используются слишком большие блоки с условиями.

Это плохо. Старайтесь всегда писать код так, что бы между блоками с условиями было не более 10 строк. Дальше код начинает теряться и сложно следить за всей логикой.

if ($a == '1') {
    // Содержимое блока
} else {
    // Другой блок
}

Так же запомните что стандартная строка должна быть не более 100 символов. Если уж совсем всё плохо, то не более 120. Любой нормальный редактор, а лучше IDE (например netbeans ) помогут вам писать аккуратный код.

Ну и в догонку ещё одно замечание по оформлению кода - обязательно прочитайте стандарт кодирования от Zend Framework . Там всё на русском, его писали умные люди что бы нам всем было легче :)

Ваш основной вопрос был - как смешивать код php + js.

Самый правильный вариант - использовать парадигму MVC. Где явно понятно, что с базой мы работаем файлах - моделях, весь код html и js находится во вьюшках, а их вместе связывает и объединяет код контроллера.

Вы всё равно приходите к тому что нужно этот код разделять, поэтому самый лучший вариант - освоить какой-нибудь простой фреймворк. Например Codeigniter или Kohana.

Ну а теперь можно приступать к коду.

PS Код я выложу завтра.. Сегоня уже не успеваю


В вашем коде прослеживается как минимум три грубейших ошибки:
- Вы смешивайте вёрстку (html) с бизнес-логикой (любыми операциями вычисления)
- В шаблоне вёрстки вы работайте с базой данных (это смертельный грех, аккуратнее)
- Используйте непроверенные ключи массивов, и неизвестные переменные

Я давно не видел подобного кода, но это совсем не повод унывать. Похоже что самое время учиться писать правильно :)

Давайте разберём пару строк вашего кода:

<?PHP if ($_GET["item"]=="create"):
           $minfo=mysql_fetch_array(mysql_query_sum("SELECT referer FROM users WHERE username='".mysql_real_escape_string($_SESSION[username])."'"));

запомните, открывающий тег всегда в нижнем регистре
<?php

ни в каких переменных поступивших от пользователя вы не должны быть уверены, поэтому всегда проверяем есть ли нужные нам ключи:

if (isset($_GET['key']) && $_GET['key'] == 'name') {}

В блоке if () : двоеточие используется только при альтернативном синтаксисе, который применяется в вёрстке шаблонов
<html>
<?php if($a = 1) : ?>
<a href="asd">a</a>
<?php endif; ?>
</html>

Удобнее было бы вынести код запроса в отдельную переменную. Более того, все переменные из запроса стоит убрать и проверять их отдельно. Например так:

$username = isset($_SESSION['username']) ? mysql_real_escape_string($_SESSION['username']) : '';
$sql = "SELECT referer FROM users WHERE username='{$username}'";
$minfo = mysql_fetch_array(mysql_query_sum($sql));

PS.. Тут я пока прервусь, если интересно - отпишитесь, и я расскажу по коду дальше.


Итак, продолжаем передачу :)

Главное что нужно усвоить - это что код всегда будет поддерживаться и поэтому его нужно писать правильно и грамотно. С вашим кодом будут всегда работать другие люди. Даже вы, спустя пару недель - будете смотреть на код по-новому. Для того что бы каждый раз не удивляться что тут такое написано, нужно прививать себе навыки стандартного кодирования. Про стандарты кодирования я рассказывал чуть ранее. А сейчас расскажу про рефакторинг.

Рефакторинг - это нормальная практика написания кода. Каждый раз после того как вы напишете код, если вы о нём сразу не забываете, его нужно приводить в порядок. Т.е. давать именам и функциям понятные имена, следовать стандартам кодирования, выносить дублирующиеся блоки в один блок, комментировать код..

Рефакторинг - это достаточно большая тема, и главное тут понять, что рефакторинг продолжается постоянно на протяжении жизни кода. Т.е. если вы работайте с классом, и понимаете что тут можно улучшить читаемость или написать более понятную и простую функцию, вы должны это делать каждый раз как приступаете работать с этим файлом.

И конечно же, нужно всегда помнить об обратной совместимости. Если ваше изменение тут повлияет на работу кода в других файлах, вы обязаны поправить и те файлы тоже.

Более подробно про рефакторинг нужно прочитать самостоятельно, книги и статьи содержат много примеров и достаточно подробны.

Я лишь приведу код который получился у меня в первой итерации.

Первое что я решил сделать - это разбить код из одного файла на несколько, где каждый файл отвечал за собственный функционал. Прежде всего я выделил код содержащий шаблоны вёрстки в два файла

Файл view/main.php

<?php
if (isset($its_ok)) {
echo "<div class=\"okay\">" . $lang['vmail_reply_ok'] . "</div>";
}
?>
<table width='100%' border='0' cellpadding='0' cellspacing='0' style='margin: 20px 0;'>
    <tr>
        <td align="center" width="33%">
            <span class="corr1" onclick="javascript:AdminClick();">
                <b>Àäìèíèñòðàöèÿ</b><br />
                <?= $site_name ?>
            </span>
        </td>
        <td align="center" width="33%">
            <?php if ($referer) : ?>
                <span class="corr2" onclick='javascript:RefClick();'>
                    <b>Ìîé ðåôåðåð</b><br />
                    <?= $referer ?>
                </span>
            <?php else : ?>
                <span class="corr2">
                    <b>Ìîé ðåôåðåð</b><br />
                    Ó âàñ íåòó ðåôåðåðà
                </span>
            <?php endif; ?>                                </td>
        <td align="center" width="33%">
            <span class="corr3" onclick="javascript:UserClick();">
                <b>Ïîëüçîâàòåëü</b><br />
                <?= $site_name ?>
            </span>
        </td>
    </tr>
</table>

<?php
if (count($errors) > 0) {
    echo "<div class='error'><ul>{$base_err[4]}";
    foreach ($errors as $error) {
        echo "<li>" . $error . "</li>";
    }
    echo "</ul></div>";
}
?>

<?php include_once dirname(__FILE__) . '/form.php';?>

Файл view/form.php

<form name="mailform" method="post" action="">
    <div class="table" style="border-top:1px solid #ba4c32;">
        <table width="100%" border="0" cellspacing="0" cellpadding="0">
            <tr>
                <td width='40%' align="right">
                    <b>Ïîëó÷àòåëü</b>
                </td>
                <td id="user">
                    <input type='text' name='login' maxlength='10' size="30" value="<?= $whom; ?>" />
                    <div style="display: none;">
                        <input type="checkbox" id="user_check" name="user_aprove" value="user_ok" checked="checked" />
                    </div>
                </td>
                <td id="admin" style="display: none;font-weight:bold;">
                    Àäìèíèñòðàöèÿ FinBUX.info
                    <div style="display: none;">
                        <input type="checkbox" id="admin_check" name="admin_aprove" value="admin_ok" />
                    </div>
                </td>
                <td id="refer" style="display: none;font-weight:bold;">
                    Ìîé ðåôåðåð
                    <u><?= $minfo["referer"] ?></u>
                <div style="display: none;">
                    <input type="checkbox" id="refer_check" name="refer_aprove" value="refer_ok" />
                </div>
                </td>
            </tr>                    
            <tr>
                <td align="right">
                    Òåìà ïèñüìà
                </td>
                <td>
                    <input type="text" name="title" maxlength="40" size="60" value="<?= $title; ?>" />
                </td>
            </tr>
            <tr>
                <td align="right">
                    Ñîäåðæàíèå ïèñüìà<br />
                    <input class="scount" type="text" name="scount" value="Îñòàëîñü 300 ñèìâîëîâ" readonly="readonly" />
                </td>
                <td>
                    <textarea cols="60" rows="3" name='message' onkeyup="descchange(this);">
                        <?= $message; ?>
                    </textarea>
                </td>
            </tr>
            <tr>
                <td colspan="2" align="center">
                    <?= $lang['CAPTCHA_ITEM'] ?>
                    <table border="0" cellpadding="0" cellspacing="1">
                        <tbody>
                            <tr>
                                <td>
                                    <img src="image.php?<?= $res; ?>" class="imgcap" alt="" />
                                </td>
                                <td>
                                    <input type="hidden" name="code" value="0">
                                    <input name="submit" value="1" onclick="vernum(this.form,1); submit();" type="submit">
                                    <input name="submit" value="2" onclick="vernum(this.form,2); submit();" type="submit">
                                    <input name="submit" value="3" onclick="vernum(this.form,3); submit();" type="submit">
                                    <input name="submit" value="4" onclick="vernum(this.form,4); submit();" type="submit"><br />
                                    <input name="submit" value="5" onclick="vernum(this.form,5); submit();" type="submit">
                                    <input name="submit" value="6" onclick="vernum(this.form,6); submit();" type="submit">
                                    <input name="submit" value="7" onclick="vernum(this.form,7); submit();" type="submit">
                                    <input name="submit" value="8" onclick="vernum(this.form,8); submit();" type="submit">
                                </td>
                            </tr>
                        </tbody>
                    </table>
                </td>
            </tr>
        </table>
    </div>
</form>

Затем файл с инструкциями index.php
<?php
/**
 * Получаем рефер
 * Важно отметить, что в каждой функции мы стараемся отделить все
 * лишние сущности друг от друга. Например из этой функции мы убрали работу с
 * сессиями, и оставили только работу с базой. Потом из неё можно будет легко
 * вынести функционал в модель
 *
 * @return string
 */

function getRefer($username)
{
    $sql        = "SELECT referer FROM users WHERE username='{$username}' LIMIT 1;";
    // Я понятия не имею что тут делала функция mysql_query_sum, но называть её с
    // тем же префиксом что и системные функции "mysql" - лучше не стоит
    $result     = mysql_fetch_array($sql);
    // Убираем непонятную переменную $myinfo, и вместо неё используем $refer
    return $result['refer'];    
}

/**
 * Апрувим пользователя
 * @global type $lang
 * @param type $username
 * @return array
 */

function aproveUser($username)
{
    // Локализацию правильнее всего сделать в виде шаблона Registry, и никогда
    // не использовать глобальные переменные
   
    global $lang;

    $errors = array();
    $whom   = trim(limpiar($_POST["login"]));
    $sql    = "SELECT COUNT(id) FROM abuses WHERE user='{$username}' AND cat='mails'";
    // Ох, не используйте пожалуйста больше конструкцию OR die.. она опасна и страшна
    // Попробуем поймать ошибку по-другому, и передать на отработку дальше
    try {
        $query = mysql_query($sql);
    } catch (Exception $e) {
        throw new Exception('Mysql error: ' . mysql_error(), E_USER_ERROR, $e);
    }
   
    // Если более трёх жалоб
    if (mysql_result($query, 0) > 3) {
        $errors[] = $lang['vmail_cr_err_1'];
    } else {
        if (empty($whom)) {
            $errors[] = $lang['vmail_cr_err_2'];
        } else {
            $sql = "select count(*) as kolvo from users WHERE username='{$username}'";
            $res = mysql_query($sql);
            $res = mysql_fetch_array($res);
           
            if ($res["kolvo"] < 1) {
                $errors[] = $lang['vmail_cr_err_3'];
            }
            if (strtolower($whom) == strtolower($username)) {
                $errors[] = $lang['vmail_cr_err_4'];
            }
        }
    }
   
    return $errors;
}

function aproveAdmin()
{
    $sql = "SELECT username, user_rights FROM `users` WHERE user_rights='admin' LIMIT 1";
    $result = mysql_query($sql);
    $admin_rows = mysql_num_rows($result);
   
    if ($admin_rows < 1) {
        $errors[] = "administratori nu exista";
    } else {
        $res = mysql_fetch_array($result);
        $whom = $res["username"];
    }
}

/**
 * Всё хорошо, сохраняемся
 *
 * @param type $username
 * @param type $whom
 * @param type $title
 * @param type $message
 */

function  all_right($username, $whom, $title, $message) {
    $sql = "INSERT INTO mails (de_la, whom, title, message, date, type)
        VALUES ('{$username}','{$whom}','{$title}','{$message}',NOW(),'send');"
;
   
    try {
        mysql_query($sql);
    } catch (Exception $e) {
        throw new Exception('Mysql error: ' . mysql_error(), E_USER_ERROR, $e);
    }    
}

if (isset($_GET["item"]) && $_GET["item"] == "create") {

    $errors        = array();

    // Получаем рефер пользователя
    if ( ! isset($_SESSION['username'])) {
        $refer      = null;
        $username   = null;
    } else {
        $refer      = getRefer($_SESSION['username']);
        $username   = mysql_real_escape_string($_SESSION['username']);
    }
   
    // Если пользователь что-то отправил
    if (isset($_POST['submit'])) {
       
        // Похоже что это функции валидации
        // А что случится, если ключа title не обнаружится в массиве $_POST?
        $title      = limpiar($_POST["title"]);
        $message    = limpiar($_POST["message"]);
       
        // Пользователь апрувлен
        if (isset($_POST["user_aprove"]) && $_POST["user_aprove"] == "user_ok") {
            $_SESSION["mail_to"] = "user_to";
            $errors += aproveUser($username);
         
        } else if (isset($_POST["admin_aprove"]) && $_POST["admin_aprove"] == "admin_ok") {
           
            $_SESSION["mail_to"] = "admin_to";
            $whom = aproveAdmin();
           
        } else if ($_POST["refer_aprove"] === "refer_ok") {
            $whom = $referer;
            $_SESSION["mail_to"] = "refer_to";
        }
        if (trim($title) == "") {
            $errors[] = $lang['vmail_cr_err_5'];
        } else {
            if (strlen($title) < 3 or strlen($title) > 40) {
                $errors[] = $lang['vmail_cr_err_6'];
            }
        }
        if (trim($message) == "") {
            $errors[] = $lang['vmail_err_6'];
        } else {
            if (strlen($message) < 10 or strlen($message) > 300) {
                $errors[] = $lang['vmail_err_3'];
            }
        }
        if (md5(strtolower($_POST['code'])) != strtolower($_SESSION['texto'])) {
            $errors[] = $base_err[2];
        }
        if (count($errors) == 0) {
            unset($_SESSION["texto"]);
            all_right($username, $whom, $title, $message);
        }
    }

    include_once dirname(__FILE__) . '/view/main.php';
}

Что можно тут сделать ещё? Можно разнести функции в отдельные файлы, можно ещё порефакторить, и найти места что я пропустил.

Но самое лучшее что я вижу - это то что вам нужно посмотореть на фреймворки, там большая часть ваших задач уже решена. Не нужно думать о том как подключать и закрывать соединенния, для куков, сессий есть свои обёртки.
Нужно начать использовать стандарты кодирования и начать применять рефакторинг.

Я рекомендую,

1) Познакомиться с основами ветвления кода, что уже вам посоветовали.

2) Используйте тернарные операторы только тогда когда они нужны, лучше всего

function test($a,$b){
   //some code
   return ($a>$b)?1:-1;
}
3) Познакомьтесь с Объектно ориентированным программированием (ООП)
Классы всегда делаю ваш код проще для понимания, кроме этого советую почитать о шаблонизаторах, т.е научитесь разделять предствления от кода, только не лезте в MVC или HMVC

4) Пробуйте, учитесь, читайте, гуглите :)