Başka bir sorunuza dayanarak bunları veritabanında tutmak istediğinizi anlıyorum.
Veritabanınızda 4 adet tablo olmalı:
1) ulkeler (şimdilik tek ülke olacak olsa da...)
id: int & primary key & auto increment
isim: text
2) bolgeler (her bölge/eyalet bir ülkeye ait olmalıdır. ulkeler tablosuyla bire çok ilişki)
id: int & primary key & auto increment
ulke_id: int
isim: text
3) iller (her il, bir bölgeye/eyalete ait olmalı)
id: int & primary key & auto increment
bolge_id: int
isim: text
4) ilceler (her ilçe, bir ile ait olmalı)
id: int & primary key & auto increment
il_id: int
isim: text
Bunlara ek olarak her ilçeye yönelik birkaç blog içeriği olabilir. İlçe seçildiğinde son yazılmış olan içeriği gösterirsiniz ve eski içeriklerin de başlıklarını gösterirsiniz. Kullanıcı tıklayınca o içeriklere de erişebilir.
5) icerikler (her içerik bir ilçeye ait olmalı)
id: int & primary key & auto increment
ilce_id: int
baslik: text
gorsel: text (içerik görselinin link'ini tutacak)
tarih: datetime (oluşturulan içerikler tarihe göre sıralanacak)
icerik: text (içerik metni html formatında burada yer alacak)
goruntulenme_sayisi: int (bunun gibi eklemeler de yapılabilir...)
Veritabanınızdaki bu tablolara manuel olarak örnek birkaç kayıt girmelisiniz. Tabi bu kayıtlar, id'ler eşleşecek şekilde tutarlı olmalı.
Örneğin:
1) ulkeler için 1 kayıt:
id: 1 (otomatik eklenecek)
isim: "Türkiye"
2) bolgeler için 1 kayıt:
id: 1 (otomatik eklenecek)
ulke_id: 1 (Türkiye'nin id'si)
isim: "Ege"
3) iller için 1 kayıt:
id: 1 (otomatik eklenecek)
bolge_id: 1 (Ege'nin id'si)
isim: "Manisa"
4) ilceler için 1 kayıt:
id: 1 (otomatik eklenecek)
il_id: 1 (Manisa'nın id'si)
isim: "Yunusemre"
5) icerikler için 1 kayıt:
id: 1 (otomatik eklenecek)
ilce_id: 1 (Yunusemre'nin id'si)
baslik: "Görülmeye değer yerler"
gorsel: https://upload.wikimedia.org/wikipedia/commons/thumb/9/94/Spil_Dağı'ndan_Yunusemre_ilçesi.jpg/500px-Spil_Dağı'ndan_Yunusemre_ilçesi.jpg
tarih: "2024-04-08 15:20:35"
icerik: "12 Kasım 2012'de Manisa il merkezinin ikiye bölünmesiyle..."
goruntulenme_sayisi: 3
Artık sayfa tasarımı başlayabilir.
Sayfada başlangıçta ülke seçimi yapılmalı. Yani ilk olarak ülkelerin veritabanından alınması gerek.
Ama her şeyden önce bazı yardımcı fonksiyonlara ihtiyacımız olacak. Mesela veritabanı bağlantısı için bir yardımcı...
Kök klasörde helpers adlı bir klasör açıp içine *database.php** adlı bir dosya oluşturabiliriz:
<?php
class Database {
private $host = "localhost";
private $dbname = "veritabani_adi";
private $username = "kullanici_adi";
private $password = "sifre";
private $conn;
public function __construct() {
$dsn = "mysql:host={$this->host};dbname={$this->dbname};charset=utf8mb4";
try {
$this->conn = new PDO($dsn, $this->username, $this->password);
$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("Bağlantı hatası: " . $e->getMessage());
}
}
public function query($sql) {
return $this->conn->query($sql);
}
public function lastInsertId() {
return $this->conn->lastInsertId();
}
public function close() {
$this->conn = null;
}
}
Artık bu yardımcı sayesinde veritabanına bağlanıp veri çekebiliriz.
Şimdi veritabanımızla iletişim kurup bize istediğimiz verileri sunacak dosyalar oluşturmalıyız.
Kök klasörde models diye bir klasör oluşturup içine ulkeler_model.php adlı bir dosya oluşturalım.
<?php
require_once('../helpers/database.php');
class Ulkeler_Model {
private $db;
public function __construct() {
$this->db = new Database();
}
public function getUlkeler() {
$sql = "SELECT * FROM ulkeler";
$result = $this->db->query($sql);
return $result->fetchAll(PDO::FETCH_ASSOC);
}
}
Şimdi de bu model dosyasıyla iletişime geçip verileri alacak ve bize uygun bir formatta iletecek olan bir dosya oluşturalım.
Kök klasörde controllers adlı bir klasör açıp içine queries.php adlı bir dosya oluşturalım.
Bu dosyaya bazı fonksiyonlar olacak. Jquery'nin ajax'ı ile işimize yarayacak koşullarda istek atacağız ve bu dosya da bize json formatında ülkelerin listesini döndürecek.
<?php
header('Content-Type: application/json');
if(!isset($_POST['query'])) {
echo json_encode(['status'=>false, 'message'=>'Sorgu belirtilmedi.']);
exit();
}
$query = $_POST['query'];
if($query==='Ülke Listesi') {
require_once('../models/ulkeler_model.php');
$ulkeler_model = new Ulkeler_Model();
$ulkeler = $ulkeler_model->getUlkeler();
echo json_encode($ulkeler);
exit();
}
Bu sayfaya query='Ülke Listesi'
verisiyle POST isteği atarsak model'imiz yardımıyla bize ülkelerin listesini döndürecek.
Bunu hemen test edebilmek için kök klasörümüze index.html dosyası oluşturabiliriz.
Bu dosyada bir select elementimiz olacak. JQuery'nin ajax'ı yardımıyla az önce oluşturduğumuz sayfaya istek atıp ülke listesini alacağız.
Json formatında aldığımız ülke listesini select elementine option olarak ekleyeceğiz. (Tabi tablomuzda sadece Türkiye olduğu için bize tek bir veri gelecek.)
Stilleri araya karıştırmadan bir örnek veriyorum:
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Blog</title>
</head>
<body>
<h1>Blog</h1>
<select id="ulkeler">
<option value="">Ülke Seçiniz</option>
</select>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function(){
// Ajax isteği ile ülke listesini al
$.ajax({
type: 'POST',
url: 'controllers/queries.php',
data: {query: 'Ülke Listesi'},
dataType: 'json',
success: function(response){
// Gelen ülke listesini select elementine ekle
response.forEach(function(ulke){
$('#ulkeler').append('<option value="' + ulke.id + '">' + ulke.isim + '</option>');
});
},
error: function(xhr, status, error){
console.error('Ajax hatası:', error);
}
});
});
</script>
</body>
</html>
Projemize localhost üzerinden gidip bu sayfayı açtığımızda controller'daki dosyamıza bir istek atılacak ve ülkeler çekilecek.
Peki seçilen ülkeye göre bölgeleri nasıl alacağız? Bunun için queries.php dosyamıza bölgeleri döndürecek bir koşul eklemeliyiz.
Ama bolgeler tablosuyla iletişim kurmak için de models klasörümüze bolgeler_model.php diye bir dosya da eklemeliyiz.
models klasöründeki bolgeler_model.php
<?php
require_once('../helpers/database.php');
class Bolgeler_Model {
private $db;
public function __construct() {
$this->db = new Database();
}
public function getBolgeler($ulke_id) {
$sql = "SELECT * FROM bolgeler WHERE ulke_id = :ulke_id";
$result = $this->db->prepare($sql);
$result->bindParam(':ulke_id', $ulke_id, PDO::PARAM_INT);
$result->execute();
return $result->fetchAll(PDO::FETCH_ASSOC);
}
}
Veritabanımızla iletişim kuracak model'imizi oluşturduk.
Artık controllers klasöründeki queries.php dosyasına gerekli koşulu ekleyebiliriz:
<?php
header('Content-Type: application/json');
if (!isset($_POST['query'])) {
echo json_encode(['status' => false, 'message' => 'Sorgu belirtilmedi.']);
exit();
}
$query = $_POST['query'];
if ($query === 'Ülke Listesi') {
require_once('../models/ulkeler_model.php');
$ulkeler_model = new Ulkeler_Model();
$ulkeler = $ulkeler_model->getUlkeler();
echo json_encode($ulkeler);
exit();
}
if ($query === 'Bölge Listesi') {
require_once('../models/bolgeler_model.php');
if (!isset($_POST['ulke_id'])) {
echo json_encode(['status' => false, 'message' => 'Ülke id belirtilmedi.']);
exit();
}
$ulke_id = $_POST['ulke_id'];
$bolgeler_model = new Bolgeler_Model();
$bolgeler = $bolgeler_model->getBolgeler($ulke_id);
echo json_encode($bolgeler);
exit();
}
Artık index.html sayfamıza bölgeler için de bir select elementi ekleyebiliriz.
JQuery ile ülke seçimindeki değişikliği algılayıp bölgeler için istek atacağız ve ilgili select'e ekleyeceğiz.
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Blog</title>
</head>
<body>
<h1>Blog</h1>
<select id="ulkeler">
<option value="">Ülke Seçiniz</option>
</select>
<select id="bolgeler">
<option value="">Bölge Seçiniz</option>
</select>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function(){
// Ülkeleri al
$.ajax({
type: 'POST',
url: 'controllers/queries.php',
data: {query: 'Ülke Listesi'},
dataType: 'json',
success: function(response){
// Gelen ülke listesini select elementine ekle
response.forEach(function(ulke){
$('#ulkeler').append('<option value="' + ulke.id + '">' + ulke.isim + '</option>');
});
},
error: function(xhr, status, error){
console.error('Ajax hatası:', error);
}
});
// Ülke seçildiğinde bölgeleri al
$('#ulkeler').change(function(){
var ulke_id = $(this).val();
$.ajax({
type: 'POST',
url: 'controllers/queries.php',
data: {query: 'Bölge Listesi', ulke_id: ulke_id},
dataType: 'json',
success: function(response){
$('#bolgeler').empty().append('<option value="">Bölge Seçiniz</option>');
// Gelen bölge listesini select elementine ekle
response.forEach(function(bolge){
$('#bolgeler').append('<option value="' + bolge.id + '">' + bolge.isim + '</option>');
});
},
error: function(xhr, status, error){
console.error('Ajax hatası:', error);
}
});
});
});
</script>
</body>
</html>
Böylece sayfa yüklendiğinde önce ülkelerin listesi alınacak ve ilgili select'e eklenecek.
Kullanıcı bir ülke seçtiğinde de bölgelerin listesi alınacak ve ilgili select'e eklenecek.
Sırada bölge seçildiğinde il, il seçildiğinde de ilçe seçimi yapmak var.
Tabi ilçe seçildiğinde de ilçenin içeriklerini alacağız ve tarihe bakarak son girilen içeriği ekranda göstereceğiz.
Sayfanın altında da bu ilçenin daha eski tarihli içeriklerini listeleyeceğiz ve bunlardan birine basıldığında o içeriğin gelmesini sağlayacağız...
...
Biraz zamanım var diye böyle uzun uzun örnekler yazdım ama artık zamanım kalmadı.
Bu noktadan sonra cevabımı olduğu gibi alıp ChatGPT'ye yapıştırarak devam etmesini söylerseniz size yardımcı olacaktır diye düşünüyorum.
Artık GPT'nin mantığı anlayacağı kadar içerik yazdım sanırım. :)
1) Veritabanı nasıl olmalı?
Aşağıda bir örnekle açıkladım.
2) İllerle ilçeleri bağlamalı mıyım?
Evet. İller ve ilçeler veritabanında tutulacaksa bir ilişkisel veritabanınız olmalı.
Tek bir tabloda yapabileceğiniz gibi, doğru olanı birkaç tabloda yapmanızdır.
Evet, illerle ilçeler arasında bir ilişki kurmak, veritabanınızı tasarlarken mantıklı bir yaklaşım olacaktır. Bu şekilde, her ilin birçok ilçesi olabilir ve her ilçe bir il ile ilişkilendirilmiş olur.
Öncelikle, bir veritabanı tasarımı için iki tabloya ihtiyacınız olacak: iller ve ilceler.
İşte bu tabloların örnek bir şeması:
iller
| id | name |
| ----------- | ----------- |
| 1 | İstanbul |
| 2 | Ankara |
| 3 | İzmir |
| 4 | Manisa |
| ... | ... |
ilceler
| id | il_id | name |
| ----------- | ------- | ----------- |
| 1 | 1 | Beyoğlu |
| 2 | 1 | Kadıköy |
| 3 | 1 | Üsküdar |
| 4 | 2 | Çankaya |
| 5 | 2 | Keçiören |
| ... | ... | ... |
Eğer her ilçe için yalnız bir resim / harita / yorum kaydı tutulacaksa, bu veriler de ilceler tablosunda tutulabilir.
Ama her bir ilçe için birden çok kayıt tutulabilecekse, bunlar için de ayrı bir tablo gerekir:
bilgiler
| id | ilce_id | yorum | gorsel |
| ----------- | --------- | -------------------------- | ------------------------------------ |
| 1 | 1 | Beyoğlu 1. yorum metni | Beyoğlu 1. yorum için görsel link'i |
| 2 | 1 | Beyoğlu 2. yorum metni | Beyoğlu 2. yorum için görsel link'i |
| 3 | 2 | Kadıköy 1. yorum metni | Kadıköy 1. yorum için görsel link'i |
| 4 | 2 | Kadıköy 2. yorum metni | Kadıköy 2. yorum için görsel link'i |
| 5 | 3 | Üsküdar 1. yorum metni | Üsküdar 1. yorum için görsel link'i |
| ... | ... | ... | ... |
Diyelim ki bir ilçenin bir resmi, bir konum bilgisi vardır. Ama birçok yorumu vardır.
O zaman ilceler tablosunda gorsel ve konum sütunları olur. bilgiler tablosunda yorum sütunu olur.
Eğer resimler ve yorumlar birbirinden bağımsızsa, yani her ilçenin bir çok görseli olabilirse ve bu görseller yoruma bağlı değilse, görseller için ayrı bir tablo yapmak da gerekebilir.
Düzeltme: markdown olarak tablo olarak oluşturdum ama cevap ekranında tablo oluşmuyor. Bu koduna @tayfunerbilen 'den geliştirme gerekiyor.
Soruyu pek anlamadım. Anladığım kadarıyla aşağıdaki örnek üzerinde sorunu daha açık yazar mısın?
Başlangıçta form şu şekilde:
<form id="addProduct">
<div id="addOption">
<buton>Yeni Opsiyon Ekle</buton>
</div>
</form>
Sonra "Yeni Opsiyon Ekle" yazan butona basıldığında:
1) Javascript ile bir ajax isteği atılıyor. (form submit edilmiyor. Sayfa yenilenmiyor.)
2) Ajax yanıtı olarak gelen verilerle içerikleri doldurulmuş şekilde, div.variantAddContent elementi javascript ile oluşturuluyor.
3) Oluşturulan div.variantAddContent elementi, "Yeni Opsiyon Ekle" yazan butonun hemen sonrasına gelecek şekilde DOM'a basılıyor.
Sonuç olarak:
<form id="addProduct">
<div id="addOption">
<buton>Yeni Opsiyon Ekle</buton>
<div class="variantAddContent gridAutoFlow" id="optionId-0">
<div class="flexColumnLeftGap10">
<label>Name</label>
<input class="input_style" type="text" name="variantAddName[0][optionName]">
</div>
<div class="flexColumnLeftGap10">
<label>Seçenek görünümü</label>
<select name="variantAddName[0][variantType]">
<option>Radyo düğmesi</option>
<option>Açılır menü</option>
<option>Renk</option>
<option>Kutu</option>
</select>
</div>
<div class="flexRow">
<div class="varyantOptionAddListParent">
<div id="varyantOptionAddList" class="flexRow">
<label>Değerler</label>
<div class="flexCenter10 variantAddRow optionListContent" id="optionValId-0">
<input class="input_style" type="text" name="variantAddName[0][optionValue][0]">
<input type="radio" id="defaultOpt0" name="variantAddName[0][optionType]" value="0" class="radioStyle">
<label for="defaultOpt0">Default</label>
<div class="varinatOptionRemove"><i class="fa-solid fa-circle-minus"></i></div>
</div>
<div class="flexCenter10 variantAddRow optionListContent" id="optionValId-1">
<input class="input_style" type="text" name="variantAddName[0][optionValue][1]">
<input type="radio" id="defaultOpt1" name="variantAddName[0][optionType]" value="1" class="radioStyle">
<label for="defaultOpt1">Default</label>
<div class="varinatOptionRemove"><i class="fa-solid fa-circle-minus"></i></div>
</div>
</div>
<div class="addVaryantOPtion" data-optionid="0">+ Yeni değer ekle</div>
</div>
</div>
</div>
<buton>Opsiyonu ekle</buton>
</div>
</form>
Burada "Opsiyonu ekle" butonuna basıldığında form
'un submit edilmesini isteniyorsa butona (button
yerine buton
yazım hatası var) type=submit attribute'si eklenmeli:
<buton>Opsiyonu ekle</buton>
yerine
<button type=submit>Opsiyonu ekle</button>
Böylece buradaki değerler PHP'ye
1) form'da method attribute'si olmadığı için varsayılan "POST" metoduyla
2) action attribute'si olmadığı için aynı sayfayı yenileyerek
iletilir ve sayfanın üstünde bu veriler şöyle yakalanabilir:
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$variantAddName = $_POST['variantAddName'];
$optionName = $variantAddName[0]['optionName'];
$variantType = $variantAddName[0]['variantType'];
$optionValue0 = $variantAddName[0]['optionValue'][0];
$optionType = $variantAddName[0]['optionType'];
// bu verilerle yapılacak işlemler...
}
?>
1) Nesne yapısına hakim değilim. Php'de "$data" dan sonra kullanılan yapıyı bilmiyorum. Prosedür "mysqli_query" tarzında yazabilirseniz ilerleyebilirim.
Veritabanından size nasıl bir sonuç dönüyor bilemiyorum. Örnek vererek ilerleyebilirim:
$sorgu = "SELECT ekle_ad, ekle_ozellik FROM tablom";
$sonuc = mysqli_query($sorgu);
if (!$sonuc) die("Sorgu çalıştırma hatası: " . mysqli_error());
$datas = [];
while ($row = mysql_fetch_assoc($sonuc)) $datas[] = $row;
Aldığınız veriyi, benim örnek verdiğim $datas
değişkenine bu şekilde doldurabilirsiniz.
Böylece $datas
değişkeniniz şöyle bir değer almış olacak:
$datas = [
["ekle_ad" => "yazilimyolcusu", "ekle_ozellik" => "Veri 1"],
["ekle_ad" => "yazilimyolcusu", "ekle_ozellik" => "Veri 3"]
];
Bu bir object'ler array'i. Object'lerin aslında array'den pek farkı yok.
Array'lerde index no ile seçim yaparsınız. Object'lerde ise key'lerle seçim yaparsınız.
Örn. $datas
dizisindeki ilk elemanı almak için: $datas[0]
Örn ilk elemandaki "ekle_ad" key'inin değerini almak için: $datas[0]->ekle_ad
2) Bir sorum olacak. Bu "checkbox_attr" değişkenlerini input'un içinde bu şekilde mi kullanacağız?
Evet. Amacınız, seçili checkbox'a checked özelliği eklemek. Bunu nasıl yapacağınız size kalmış. Benim gösterdiğim bir yol sadece.
Ana dizindeki htaccess dosyasına şu ekleme yapılabilir:
RewriteEngine On
RewriteBase /
# /panel/user isteğini /panel/index.php'ye yönlendir
RewriteRule ^panel/user$ panel/index.php [L]
Input'lara php ile veri basılıyorsa, input için value özelliği kullanılır ama checkbox için checked özelliği kullanılır.
Veritabanından aldığın veriyi hangi değişkenlerle aldığını bilmediğim için uyduracağım:
Tüm kayıtları çektiysen (örneğimizde Veri 1 ve Veri 3 olm.üz. 2 kayıt var) şöyle bir değişkenin var diye varsayalım:
$datas = [
["ekle_ad" => "yazilimyolcusu", "ekle_ozellik" => "Veri 1"],
["ekle_ad" => "yazilimyolcusu", "ekle_ozellik" => "Veri 3"]
];
Bu durumda ekle_ad bölümü zaten aynı olduğu için ilk kaydı alabiliriz:
$ad = $datas[0]->ekle_ad;
ekle_ozellik verilerini de düz bir dizi içinde toplarsak html içine gömmek kolaylaşır.
foreach($datas as $data) $aktifOzellikler[] = $data->ekle_ozellik;
// $aktifOzellikler dizisi şöyle oldu: ["Veri 1", "Veri 3"]
$checkbox1_attr = array_search("Veri 1", $aktifOzellikler)===false ? '' : 'checked'; // 'checked'
$checkbox2_attr = array_search("Veri 2", $aktifOzellikler)===false ? '' : 'checked'; // ''
$checkbox3_attr = array_search("Veri 3", $aktifOzellikler)===false ? '' : 'checked'; // 'checked'
<form action="x.php" method="post">
<input class="x-text" type="text" name="ad" placeholder="Ad" value="<?=$ad?>" ><br>
<input class="x-checkbox" type="checkbox" <?=$checkbox1_attr?> name="ozellikler[]" value="Veri 1" placeholder="Veri 1" ><br>
<input class="x-checkbox" type="checkbox" <?=$checkbox2_attr?> name="ozellikler[]" value="Veri 2" placeholder="Veri 2" ><br>
<input class="x-checkbox" type="checkbox" <?=$checkbox3_attr?> name="ozellikler[]" value="Veri 3" placeholder="Veri 3" ><br>
</form>
Kodları denemeden direkt buraya yazdığım için syntax hataları veya kurgusal hatalar olabilir.
$ad = $_POST['ad'];
$ozellikler = $_POST['ozellikler'];
Burada $ozellikler
dizisi yalnızca seçili checkbox'ların değerlerini taşır.
Mesela "Veri 1" ve "Veri 3" seçili, "Veri 2" seçili değil.
O zaman $ozellikler
dizisi şunu içerir: ["Veri 1", "Veri 3"]
foreach($ozellikler as $ozellik) {
$query = "INSERT INTO ekle (ekle_ad, ekle_ozellik) VALUES ('$ad', '$ozellik')";
// diğer işlemler...
}
Burada ekle_ozellik
alanına $ozellik
değerini atıyoruz.
Yukarıdaki örneğe göre "Veri 1" ve "Veri 3" için 2 kez insert sorgusu çalışacak, yani 2 kayıt insert edilmiş olacaktır.
form tarafında input'lara php ile veri basılıyorsa, input için value özelliği kullanılır ama checkbox için checked özelliği kullanılır.
Veritabanından aldığın veriyi hangi değişkenlerle aldığını bilmediğim için uyduracağım:
Tüm kayıtları çektiysen (örneğimizde Veri 1 ve Veri 3 olm.üz. 2 kayıt var) şöyle bir değişkenin var diye varsayalım:
$datas = [
["ekle_ad" => "yazilimyolcusu", "ekle_ozellik" => "Veri 1"],
["ekle_ad" => "yazilimyolcusu", "ekle_ozellik" => "Veri 3"]
];
Bu durumda ekle_ad bölümü zaten aynı olduğu için ilk kaydı alabiliriz:
$ad = $datas[0]->ekle_ad;
ekle_ozellik verilerini de düz bir dizi içinde toplarsak html içine gömmek kolaylaşır.
foreach($datas as $data) $aktifOzellikler[] = $data->ekle_ozellik;
// $aktifOzellikler dizisi şöyle oldu: ["Veri 1", "Veri 3"]
$checkbox1_attr = array_search("Veri 1", $aktifOzellikler)===false ? '' : 'checked'; // 'checked'
$checkbox2_attr = array_search("Veri 2", $aktifOzellikler)===false ? '' : 'checked'; // ''
$checkbox3_attr = array_search("Veri 3", $aktifOzellikler)===false ? '' : 'checked'; // 'checked'
<form action="x.php" method="post">
<input class="x-text" type="text" name="ad" placeholder="Ad" value="<?=$ad?>" ><br>
<input class="x-checkbox" type="checkbox" <?=$checkbox1_attr?> name="ozellikler[]" value="Veri 1" placeholder="Veri 1" ><br>
<input class="x-checkbox" type="checkbox" <?=$checkbox2_attr?> name="ozellikler[]" value="Veri 2" placeholder="Veri 2" ><br>
<input class="x-checkbox" type="checkbox" <?=$checkbox3_attr?> name="ozellikler[]" value="Veri 3" placeholder="Veri 3" ><br>
</form>
Kodları denemeden direkt buraya yazdığım için syntax hataları veya kurgusal hatalar olabilir.
SQL injection açığından kurtulmak için PDO kullanmalısın.
XSS açığından korunmak için de ekrana basacağın verileri htmlspecialchars()
ile düzenlemen yeterli.
XSS açığını doğuran şey, tarayıcının yorumlayabileceği verinin DOM'a basılması.
Yalnızca veriyi ekrana basarken buna dikkat etmen yeterli olur.
Ama eğer veritabanına htmlspecialchars()
ile eklersen, ekrana basarken tekrar htmlspecialchars()
tekrar ile düzenlemene gerek kalmaz.
Bana sorarsan veritabanında verinin orijinal halini (sql injection'dan sakınarak) saklamalısın. Sadece veriyi ekrana basarken htmlspecialchars()
ile basmalısın.
Öncelikle alanları açacak butonları ayarlayalım.
Bu butonları kendimizce gruplandırmak için "sectionTabButton" diye bir class ekleyelim.
Hangi butonun hangi alanı açacağını belirtmek için de data-target-id
gibi bir attribute ekleyelim.
Sonra içeriklerinizi tutacak alanlar için de "sectionContent" diye bir class ekleyelim.
Bu içeriklerin hangi butonla bağlantılı çalışacağını belirlemek için de data-section-id
diye bir attribute ekleyelim.
Hangi alanın aktif olduğunu belirtmek için de "active" class'ını kullanalım.
Başlangıçta ilk alanın aktif olması için hem ilgili butona hem içeriğe bu class'ı ekleyelim.
<div>
<button class="sectionTabButton active" data-target-id="1">Alan 1</button>
<button class="sectionTabButton" data-target-id="2">Alan 2</button>
<button class="sectionTabButton" data-target-id="3">Alan 3</button>
<button class="sectionTabButton" data-target-id="4">Alan 4</button>
<button class="sectionTabButton" data-target-id="5">Alan 5</button>
<button class="sectionTabButton" data-target-id="6">Alan 6</button>
</div>
<div>
<div class="sectionContent active" data-section-id="1">Alan 1 içeriği</div>
<div class="sectionContent" data-section-id="2">Alan 2 içeriği</div>
<div class="sectionContent" data-section-id="3">Alan 3 içeriği</div>
<div class="sectionContent" data-section-id="4">Alan 4 içeriği</div>
<div class="sectionContent" data-section-id="5">Alan 5 içeriği</div>
<div class="sectionContent" data-section-id="6">Alan 6 içeriği</div>
</div>
Yalnızca "active" class'ına sahip içeriğin görünmesini, diğerlerinin gizli kalmasını istiyoruz.
Bunu javascript ile yapmak yerine css ile yapabiliriz.
.sectionContent { display:none /*...alanın diğer stilleri*/ }
.sectionContent.active { display:block; }
Şimdi butonları işler hale getiren script'i yazabiliriz.
Bir butona basıldığında, "active" class'lı butonun ve içeriğin bu class'ı silinmeli.
Basılan butona ve buna bağlı içeriğe "active" class'ı eklenmeli.
const $sectionTabButtons = document.querySelectorAll(".sectionTabButton");
const $sectionContents = document.querySelectorAll(".sectionContent");
// Aşağıdaki script'i üşendiğim için ChatGPT 3.5'e yazdırdım...
$sectionTabButtons.forEach(function ($button) {
$button.addEventListener("click", function () {
// Tüm butonlardan "active" class'ını kaldır
$sectionTabButtons.forEach($btn => {
$btn.classList.remove("active");
});
// Tüm içerik alanlarından "active" class'ını kaldır
$sectionContents.forEach($content => {
$content.classList.remove("active");
});
// Basılan butona "active" class'ını ekle
$button.classList.add("active");
// İlgili içeriği bul ve ona "active" class'ını ekle
const targetId = button.getAttribute("data-target-id");
const $targetContent = document.querySelector('.sectionContent[data-section-id="'+targetId+'"]');
$targetContent.classList.add("active");
});
});
Başına $ koyduğum değişkenler: Genel olarak bir değişkenin bir element tuttuğunu belirtmek için değişkenin başına $ işareti koyulur.
Zorunluluk değildir ama js geliştiricileri arasında bir standart olarak, kod anlaşılırlığını kolaylaştırmak için kullanılıyor.
Malesef ben de göremedim. Çin merkezli DCloud firması tarafından hazırlandığı için tüm kaynaklar da ona göre hazırlanmış.
Bu durumda ChatGPT, Gemini gibi bir aracı kullanarak dokümantasyonu takip etmek için ek bir çabaya girmek gerek.
- Gemini 1.0 Pro ile denedim ama düzgün cevaplar alamadım. Yalan yanlış bilgiler...
- ChatGPT 3.5 ile denediğimde daha düzgün cevaplar aldım. Önce uni-app'in ne olduğunu anladığından emin olduktan sonra dokümantasyon içeriğini (doğrudan erişemediği için kopyala-yapıştır ile) çevirmesini istedim ve detaylı olmasa da anlaşılır bir çeviri sundu. Detaylar için ayrıca soru-cevap şeklinde ilerlemek gerek tabi...
ChatGPT konuşmamı link vererek paylaşmak istedim ama nedense hata aldım.
Nitekim, Çin projesi olduğu için muhtemelen batı dünyasında karşılık bulmayacaktır. Haliyle düzgün İngilizce kaynak sıkıntısı hep olacaktır diye düşünüyorum. Zaten kendileri bile İngilizce içeriğe özen göstermemişler gibi görünüyor. Bu durumda, geliştirme sırasında karşınıza çıkabilecek çeşitli hataları araştırdığınızda da hep Çince sorular ve yanıtlarla karşılaşacaksınız diye düşünüyorum.
Sanırım React ile cross platform geliştirme yapmak yerine Vue ile yapmak istediğiniz için uni-app öğrenmek istiyorsunuz.
Bu durumda Vue Native önerebilirim. Tekerleği yeniden icat etmek yerine React Native altyapısını kullanır ama üst katman olarak sizin Vue kullanmanızı sağlar. İnceleyebilirsiniz...