Nasıl php scriptler (kodlama tarzı) da sql sorguları gömülü mı?

10 Cevap php

Eğer php sql komut nasıl embed? Sadece bir dize veya bir yorumlu metin bunları yazmak mı yoksa bir sql dosyasına dışarıdan mı? Onları outsource en iyi yöntemler var mı? Bu düzenlemek için zarif bir yolu var mı?

10 Cevap

ORM (Object-Relational Mapping) tabakası ile bir çerçeve kullanın. Bu şekilde her yerde düz SQL koymak zorunda değilsiniz. Gömülü SQL okunabilirlik, bakım ve her şey için berbat.

Her zaman giriş kaçmak için hatırlıyorum. , Manuel olarak yapmak hazırlanmış deyimleri kullanmayın. İşte benim raporlama sınıftan bir örnek yöntemidir.

public function getTasksReport($rmId, $stage, $mmcName) {
    $rmCondition = $rmId ? 'mud.manager_id = :rmId' : 'TRUE';
    $stageCondition = $stage ? 't.stage_id = :stageId' : 'TRUE';
    $mmcCondition = $mmcName ? 'mmcs.username = :mmcName' : 'TRUE';
    $sql = "
            SELECT
                    mmcs.id AS mmc_id,
                    mmcs.username AS mmcname,
                    mud.band_name AS mmc_name,
                    t.id AS task_id,
                    t.name AS task, 
                    t.stage_id AS stage,
                    t.role_id,
                    tl.id AS task_log_id,
                    mr.role,
                    u.id AS user_id,
                    u.username AS username,
                    COALESCE(cud.full_name, bud.band_name) AS user_name,
                    DATE_FORMAT(tl.completed_on, '%d-%m-%Y %T') AS completed_on,
                    tl.url AS url,
                    mud.manager_id AS rm_id
            FROM users AS mmcs
            INNER JOIN banduserdetails AS mud ON mud.user_id = mmcs.id
            LEFT JOIN tasks AS t ON 1
            LEFT JOIN task_log AS tl ON tl.task_id = t.id AND tl.mmc_id = mmcs.id
            LEFT JOIN mmc_roles AS mr ON mr.id = t.role_id
            LEFT JOIN users AS u ON u.id = tl.user_id
            LEFT JOIN communityuserdetails AS cud ON cud.user_id = u.id
            LEFT JOIN banduserdetails AS bud ON bud.user_id = u.id
            WHERE mmcs.user_type = 'mmc'
                    AND $rmCondition
                    AND $stageCondition
                    AND $mmcCondition
            ORDER BY mmcs.id, t.stage_id, t.role_id, t.task_order
    ";
    $pdo = new PDO(.....);
    $stmt = $pdo->prepare($sql);
    $rmId and $stmt->bindValue('rmId', $rmId); // (1)
    $stage and $stmt->bindValue('stageId', $stage); // (2)
    $mmcName and $stmt->bindValue('mmcName', $mmcName); // (3)
    $stmt->execute();
    return $stmt->fetchAll();
}

İşaretli hatları (1), (2) ve (3) Koşullu bağlama için bir yol göreceksiniz.

Basit sorgular için elle SQL bina ihtiyacını azaltmak için ORM çerçeve kullanmak.

Bu sorgu büyüklüğü ve zorluk bağlıdır.

I personally like heredocs. But I don't use it for a simple queries. That is not important. The main thing is "Never forget to escape values"

Her zaman gerçekten HER ZAMAN değişkenler için yer sahipleri ile tablolarını kullanmalısınız.

Onun biraz daha kod, ama çoğu veritabanları daha verimli çalışır ve SQL injection saldırılarına karşı sizi korur.

Ben normalde işlevi argüman olarak bunları yazmak:

db_exec ("SELECT ...");

Sql olacak çok büyük zaman haller dışında, ben değişken olarak geçmesi:

$SQL = "SELECT ...";
$result = db_exec ($SQL);

(Ben veritabanı işlemleri için sarıcı-işlevleri veya nesneleri kullanın)

$ Sql ​​= sprintf ("SELECT * FROM uyeler WHERE id =% d" ($ _GET ["id"]) mysql_real_escape_string,);

MySQL enjeksiyon Güvenli

Bir ORM veya bir sql dizesi oluşturucu kullanmak, ancak bazı karmaşık sorgular yazma sql gerektirir. Sql yazarken, Michał Slaby gösterdiği gibi, sorgu bağlamaları kullanın. Sorgu bağlamaları SQL enjeksiyon önlemek ve okunabilirliği korumak. Sorguları nereye koymak gelince: modeli sınıfları kullanabilirsiniz.

Eğer belli bir seviyeye olsun, size yazmak SQL% 99 otomatik olabilir biliyoruz. Eğer bir özellikler dosyasındaki düşünmek çok sorguları yazarsanız, muhtemelen basit olabilir bir şey yapıyoruz:

Biz programcılar yapmak şeylerin çoğunu CRUD: Oku Güncelle Sil oluşturun

Kendim için bir araç olarak, ben Pork.dbObject inşa. 2 basit sınıflar (Veritabanı Soyutlama + DBObject class) nesne ilişkisi Mapper + Active Record

Sitemden örnek bir çift:

Create a weblog:

    $weblog = new Weblog(); // create an empty object to work with. 
    $weblog->Author = 'SchizoDuckie'; // mapped internally to strAuthor. 
    $weblog->Title = 'A test weblog';  
    $weblog->Story = 'This is a test weblog!'; 
    $weblog->Posted = date("Y-m-d H:i:s"); 
    $weblog->Save(); // Checks for any changed values and inserts or updates into DB. 
    echo ($weblog->ID) // outputs: 1

And one reply to it:

    $reply = new Reply(); 
    $reply->Author = 'Some random guy'; 
    $reply->Reply = 'w000t'; 
    $reply->Posted = date("Y-m-d H:i:s"); 
    $reply->IP = '127.0.0.1'; 
    $reply->Connect($weblog); // auto-saves $reply and connects it to $weblog->ID

And, fetch and display the weblog + all replies:

    $weblog = new Weblog(1); //Fetches the row with primary key 1 from table weblogs and hooks it's values into $weblog;

    echo("<h1>{$weblog->Title}</h1> 
    <h3>Posted by {$weblog->Author} @ {$weblog->Posted}</h3> 
    <div class='weblogpost'>{$weblog->Story}</div>"); 

    // now fetch the connected posts. this is the real magic: 
    $replies = $weblog->Find("Reply"); // fetches a pre-filled array of Reply objects. 
    if ($replies != false) 
    { 
        foreach($replies as $reply) 
        { 
            echo("<div class='weblogreply'><h4>By {$reply->Author} @ {$reply->Posted}</h4> {$reply->Reply}</div>"); 
        } 
    }

The weblog object would look like this:

class Weblog extends dbObject 
{ 
    function __construct($ID=false) 
    { 
        $this->__setupDatabase('blogs', // database table 
        array('ID_Blog' => 'ID',    // database field => mapped object property 
            'strPost' => 'Story',    // as you can see, database field strPost is mapped to $this->Story 
            'datPosted' => 'Posted', 
            'strPoster' => 'Author', 
            'strTitle'  => 'Title',
            'ipAddress'  => 'IpAddress', 
            'ID_Blog',    // primary table key  
            $ID);    // value of primary key to init with (can be false for new empty object / row) 
        $this->addRelation('Reaction'); // define a 1:many relation to Reaction 

    }
}

See, no manual SQL writing :) Link + more examples: Pork.dbObject

Pork.Generator: Ah evet ben de benim iskele aracı için bir ilkel GUI oluşturdu

Ben gibi tercihim:

$sql = "SELECT tbl1.col1, tbl1.col2, tbl2.col1, tbl2.col2"
        . " FROM Table1 tbl1"
        . " INNER JOIN Table2 tbl2 ON tbl1.id = tbl2.other_id"
        . " WHERE tbl2.id = ?"
        . " ORDER BY tbl2.col1, tbl2.col2"
        . " LIMIT 10, 0";

Tüm dizeleri bitiştirmek için bir nebze daha uzun PHP sürebilir ama çok güzel görünüyor ve düzenlemek için daha kolay olduğunu düşünüyorum.

Kesinlikle son derece uzun ve uzman sorguları için bir. Sql dosyayı okumak ya da bir saklı yordam kullanmak mantıklı olur. : Sizin çerçeveye bağlı olarak, bu kadar basit olabilir

$sql = (string) View::factory('sql/myfile');

(Eğer gerekirse görünümü / şablon değişkenleri atamak seçeneği sunan). Bir çiftleşmiş motoru veya çerçeve yardımı olmadan, kullanmak istiyorum:

$sql = file_get_contents("myfile.sql");

Umarım bu yardımcı olur.

Ben bu formatı istiyorum. Bir önceki açıklamada belirtilen, ancak hizalama bana kapalı gibiydi.

$query = "SELECT "
       . " foo, "
       . " bar "
       . "FROM "
       . " mytable "
       . "WHERE "
       . " id = $userid";

Okumak ve anlamak için yeterince kolay. Noktalar eşittir temiz bir çizgide her şeyi tutmak işaretiydi ile hizaya.

Ben yukarıda benim örnekte $ adınız gibi değişkenler ile çalışmak nasıl olurdu emin değilim ancak ben de ayrı bir dosyaya SQL tutma fikrini seviyorum.