PHP ile otomasyon dendiğinde çoğu kişinin aklına cron job’lar ve e-posta gönderme işlemleri gelir. Oysa otomasyonun kapsamı çok daha geniştir: dosya işleme, veri transferi, API entegrasyonları, rapor üretimi ve hatta sunucu yönetimi gibi süreçler de PHP ile otomatikleştirilebilir. Bu yazıda, gerçek projelerde kullanabileceğiniz somut kod örnekleriyle PHP otomasyon sistemlerini ele alıyoruz.
Hedef kitlesi olarak PHP’ye temel düzeyde hâkim olan geliştiricileri düşündüm. Yani değişken, döngü ve fonksiyonları bilen ancak otomasyon konusunda nereden başlayacağını merak edenler için faydalı olacak bir rehber hazırladım. Amacım, herkesin kendi projesine uyarlayabileceği, çalışan kod parçacıkları sunmak.
Otomasyonun Temel Yapı Taşları: Cron Job ve Zamanlama
PHP betiklerini belirli zamanlarda çalıştırmanın en yaygın yolu cron job kullanmaktır. Sunucunuzda crontab üzerinden bir satır ekleyerek PHP betiğinizi dakikada, saatte ya da günde bir çalıştırabilirsiniz. Örnek bir satır:
0 3 * * * /usr/bin/php /home/kullanici/public_html/betikekran.php
Bu satır her gece saat 03:00’te betikekran.php dosyasını çalıştırır. Cron job’ların en büyük avantajı, sunucu yeniden başlatılsa bile ayarların korunmasıdır. Ancak dikkat edilmesi gereken bazı noktalar var:
- PHP betiğinin tam yolunu yazın; göreceli yollar sorun çıkarabilir.
- Betik çıktısını bir log dosyasına yönlendirin:
0 3 * * * /usr/bin/php /home/.../betik.php >> /home/.../log.txt 2>&1 - Eğer Windows sunucu kullanıyorsanız, Görev Zamanlayıcı üzerinden benzer işlemleri yapabilirsiniz.
Cron job’lar her ne kadar güçlü olsa da, bazen otomasyonu web tabanlı bir arayüzden yönetmek isteyebilirsiniz. Bu durumda kendi zamanlayıcı sisteminizi yazmanız gerekebilir. Özellikle paylaşımlı hosting kullanıyorsanız ve crontab’a erişiminiz yoksa, bir web tabanlı zamanlayıcı işe yarar.
Web Tabanlı Zamanlayıcı: Basit Bir Örnek
Aşağıdaki örnek, bir veritabanındaki görevleri kontrol eder ve süresi gelmiş olanları çalıştırır. Bu yaklaşım, her sayfa yüklendiğinde veya ayrı bir cron olarak çalıştırılabilir.
// scheduled_tasks.php
$tasks = $db->query("SELECT * FROM tasks WHERE next_run <= NOW()")->fetchAll();
foreach ($tasks as $task) {
// Görevi çalıştır
$result = runTask($task['command']);
// Bir sonraki çalışma zamanını güncelle
$db->exec("UPDATE tasks SET next_run = DATE_ADD(NOW(), INTERVAL " . $task['interval_minutes'] . " MINUTE) WHERE id = " . $task['id']);
// Log tut
$db->exec("INSERT INTO task_logs (task_id, status, created_at) VALUES (" . $task['id'] . ", '" . ($result ? 'success' : 'error') . "', NOW())");
}
function runTask($command) {
// Komutu çalıştır, çıktıyı yakala
exec($command, $output, $return_var);
return $return_var === 0;
}
Bu sistemin en büyük avantajı, görevleri veritabanından yönetebilmenizdir. Yeni bir görev eklemek veya zaman aralığını değiştirmek için sadece bir SQL sorgusu yazmanız yeterli.
Dosya ve Klasör Otomasyonu
Dosya sistemiyle uğraşmak, otomasyonun en sık ihtiyaç duyulan alanlarından biridir. Örneğin, bir klasördeki dosyaları düzenli olarak yedeklemek, eski dosyaları silmek veya dosya adlarını düzenlemek isteyebilirsiniz. PHP’nin FilesystemIterator sınıfı bu işler için idealdir.
Belirli Bir Klasördeki Eski Dosyaları Silme
Aşağıdaki kod, belirli bir klasörde 30 günden eski olan .tmp uzantılı dosyaları siler:
$dir = '/tmp/otomasyon';
$date = new DateTime();
$date->modify('-30 days');
$iterator = new FilesystemIterator($dir);
foreach ($iterator as $file) {
if ($file->isFile() && $file->getExtension() === 'tmp') {
if ($file->getMTime() < $date->getTimestamp()) {
unlink($file->getPathname());
echo 'Silindi: ' . $file->getFilename() . PHP_EOL;
}
}
}
Bu kod, getMTime() ile dosyanın son değiştirilme zamanını alır ve belirlenen tarihten önceyse dosyayı siler. Dikkat etmeniz gereken nokta, dosya adı ve yol güvenliğidir. Kullanıcı girdisinden gelen yolları kullanacaksanız mutlaka doğrulayın.
Klasör İçindeki Dosyaları Arşivleme
Bir klasördeki tüm dosyaları zip arşivine almak için ZipArchive sınıfını kullanabilirsiniz:
$zip = new ZipArchive();
$archivePath = '/backups/todays-backup-' . date('Ymd') . '.zip';
if ($zip->open($archivePath, ZipArchive::CREATE | ZipArchive::OVERWRITE) === true) {
$dir = '/files/to-backup';
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($dir),
RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($files as $name => $file) {
if (!$file->isDir()) {
$filePath = $file->getRealPath();
$relativePath = substr($filePath, strlen($dir) + 1);
$zip->addFile($filePath, $relativePath);
}
}
$zip->close();
echo 'Arşiv oluşturuldu: ' . $archivePath;
}
Bu örnek, klasördeki tüm dosyaları (alt klasörler dahil) zip olarak paketler. RecursiveIteratorIterator kullanmak, iç içe klasörleri de otomatik olarak tarar. Arşiv ismine tarih eklediğimiz için her gün farklı bir dosya oluşur; eski arşivleri silmek için ayrı bir otomasyon kurabilirsiniz.
E-posta Gönderimini Otomatikleştirme
E-posta, otomasyonun vazgeçilmezlerindendir. Sipariş onayları, raporlar, bilgilendirmeler… Bunların hepsini zamanlanmış PHP betikleriyle gönderebilirsiniz. Ancak e-posta gönderimi sandığınız kadar basit değildir; teslim edilebilirlik, spam filtreleri ve bağlantı hataları gibi konulara dikkat etmeniz gerekir.
PHP ile E-posta Gönderme: mail() Fonksiyonu
PHP’nin temel mail() fonksiyonu basit işler için yeterlidir, ancak güvenilirlik açısından sınırlıdır. Özellikle toplu e-posta gönderimlerinde veya zengin içerikli e-postalarda yetersiz kalır. Yine de küçük projeler için hızlı bir çözüm olabilir:
$to = 'alici@ornek.com';
$subject = 'Günlük Rapor';
$message = 'Günlük Rapor
' . $raporIcerik . '
';
$headers = "From: webmaster@ornek.com
";
$headers .= "Content-Type: text/html; charset=UTF-8
";
if (mail($to, $subject, $message, $headers)) {
echo 'E-posta gönderildi.';
} else {
error_log('E-posta gönderilemedi.');
}
Bu yöntemde başlık bilgilerine dikkat edin. UTF-8 karakter seti belirtmezseniz, Türkçe karakterler bozuk görünebilir. Ayrıca mail() fonksiyonunun çalışması için sunucuda bir MTA (Mail Transfer Agent) kurulu olması gerekir; çoğu paylaşımlı hosting bunu sağlar.
Güvenilir E-posta için PHPMailer ve SMTP
Gönderim başarısı ve teslim edilebilirlik önemliyse, PHPMailer kütüphanesini SMTP ile kullanmak en iyi yöntemdir. SMTP, e-postanızın doğrudan bir posta sunucusu üzerinden gitmesini sağlar ve kimlik doğrulama imkânı tanır. Örnek:
use PHPMailerPHPMailerPHPMailer;
use PHPMailerPHPMailerSMTP;
use PHPMailerPHPMailerException;
require 'vendor/autoload.php';
$mail = new PHPMailer(true);
try {
$mail->isSMTP();
$mail->Host = 'smtp.example.com';
$mail->SMTPAuth = true;
$mail->Username = 'otomasyon@example.com';
$mail->Password = 'sifre';
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->Port = 587;
$mail->setFrom('otomasyon@example.com', 'Otomasyon');
$mail->addAddress('alici@example.com');
$mail->isHTML(true);
$mail->Subject = 'İşte günlük raporunuz';
$mail->Body = 'Merhaba, günlük rapor ektedir.
';
$mail->AltBody = 'Merhaba, günlük rapor ektedir.';
$mail->send();
echo 'E-posta gönderildi';
} catch (Exception $e) {
echo "Hata: {$mail->ErrorInfo}";
}
Burada dikkat edilmesi gereken nokta, SMTP bilgilerini sabit kodlamak yerine bir yapılandırma dosyasında tutmaktır. Ayrıca hata yönetimi önemlidir; e-posta gönderilemezse kullanıcıyı bilgilendirmek veya loglamak gerekir.
API Entegrasyonları ve Otomatik Veri Alışverişi
İnternet servislerinin çoğu API sunar. Bu API’leri kullanarak harici sistemlerden veri çekebilir veya veri gönderebilirsiniz. PHP’nin cURL kütüphanesi bu işler için standarttır. Örneğin, bir e-ticaret siteniz varsa ve stokları her gece harici bir tedarikçi API’sinden güncellemek istiyorsanız, cURL ile bunu otomatikleştirebilirsiniz.
Google Sheets’ten Veri Çekme (Örnek)
Aşağıdaki örnek, Google Sheets API üzerinden bir tablodan verileri çekip PHP dizisine dönüştürür. Ancak bu örnek sadece konsepti göstermek içindir; gerçek API çağrısı OAuth 2.0 gerektirir ve daha karmaşıktır.
function googleSheetsApiOku($spreadsheetId, $range) {
$url = "https://sheets.googleapis.com/v4/spreadsheets/{$spreadsheetId}/values/{$range}";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . getAccessToken(),
'Accept: application/json'
]);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true)['values'] ?? [];
}
Burada getAccessToken() fonksiyonu, OAuth 2.0 ile elde edilen erişim token’ını döndürür. Token’ın süresi dolarsa yenilemek gerekir. Bu işlemleri adım adım yapmak zahmetlidir, bu yüzden Google API istemci kütüphanesini kullanmak daha pratiktir. Yine de cURL ile çalışmak, temel mantığı anlamanızı sağlar.
REST API Çağrıları İçin Dosyalama
Aynı cURL yapısını başka API’ler için de kullanabilirsiniz. Örneğin, bir SMS servisine otomatik mesaj göndermek:
function sendSms($telefonNo, $mesaj) {
$apiUrl = 'https://api.smsprovider.com/v1/mesaj-gonder';
$postData = json_encode([
'telefon' => $telefonNo,
'mesaj' => $mesaj
]);
$ch = curl_init($apiUrl);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POSTFIELDS => $postData,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Authorization: Bearer ' . API_KEY
]
]);
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
Bu örnekte sabit gibi görünen API_KEY aslında bir sabit olabilir ancak güvenlik için bir ortam değişkeninde tutulması daha doğrudur. Özellikle kod herkesin görebileceği bir depoda yer alıyorsa, API anahtarlarını açığa çıkarmamak gerekir.
Veritabanı Yedekleme ve Raporlama
Veritabanı yedekleme, otomasyonun en kritik görevlerinden biridir. MySQL için mysqldump komutu PHP’den çalıştırılabilir. Ayrıca düzenli raporlar oluşturup e-posta ile göndermek de yaygın bir kullanım şeklidir.
MySQL Veritabanını Otomatik Yedekleme
function backupDatabase($host, $user, $pass, $dbname) {
$date = date('Y-m-d_H-i-s');
$filename = "/backups/{$dbname}_{$date}.sql";
exec("mysqldump -h {$host} -u {$user} -p{$pass} {$dbname} > {$filename} 2>&1", $output, $return);
if ($return === 0) {
return $filename;
}
error_log('Veritabanı yedekleme hatası: ' . implode('
', $output));
return false;
}
Burada mysqldump komutunu çalıştırdık. Ancak çıktıyı doğrudan ekrana yazdırmak yerine bir dosyaya yönlendirdik. Hata durumunda hata mesajlarını loglayabilirsiniz. Dikkat: Bu yöntemde komut satırı güvenliği önemlidir; eğer kullanıcı girdisi kullanıyorsanız kaçış fonksiyonları uygulayın.
Yedek dosyalarınızı sunucuda tutmak yerine bir depolama servisine (örn. Amazon S3) göndermek de mümkündür. Bu durumda yukarıdaki fonksiyonun çıktı dosyasını bir API ile hedefe ulaştırabilirsiniz.
Günlük Raporu E-posta ile Gönderme
Aşağıdaki örnek, dünkü siparişlerin özetini çıkarıp yöneticiye e-posta ile gönderir. Bu işlemi cron ile her sabah 08:00’de çalıştıracak şekilde planlayabilirsiniz.
$dun = date('Y-m-d', strtotime('-1 day'));
$siparisler = $db->query("SELECT COUNT(*) as adet, SUM(tutar) as toplam FROM siparisler WHERE DATE(olusturma_tarihi) = '$dun'")->fetch();
$icerik = "Günlük Sipariş Raporu
";
$icerik .= "Tarih: $dun
";
$icerik .= "Toplam Sipariş: {$siparisler['adet']}
";
$icerik .= "Toplam Ciro: {$siparisler['toplam']} TL
";
// PHPMailer veya mail() ile gönder
$mail = new PHPMailer(true);
// ... konfigürasyon ve gönderim
Rapor içeriğini HTML olarak hazırlamak, e-postanın daha okunaklı olmasını sağlar. Ancak e-posta istemcilerinin çoğu gömülü stil desteklemediğinden, basit tutmakta fayda var.
Sunucu Yönetimi ve İzleme Otomasyonu
PHP sadece web uygulamaları için değil, sunucu yönetiminde de kullanılabilir. Disk alanı kontrolü, CPU kullanımı, çalışmayan servislerin yeniden başlatılması gibi işlemler otomatikleştirilebilir. Kabul edelim, PHP bu konuda ideal bir dil değildir; ancak mevcut sistemlerle entegre olmak için pratik olabilir.
Disk Alanı Uyarısı Gönderme
Sunucudaki disk kullanımı belirli bir eşiği aştığında e-posta ile uyarı göndermek isteyebilirsiniz. Aşağıdaki örnek, komut ile disk kullanımını alır ve yorumlar:
$disk = disk_free_space('/');
$toplam = disk_total_space('/');
$yuzde = round((($toplam - $disk) / $toplam) * 100, 2);
if ($yuzde > 90) {
$mesaj = "Sunucu disk kullanımı %{$yuzde} oldu.";
// E-posta gönder
}
Bu fonksiyonları cron ile ayrı bir betikte çalıştırabilirsiniz. Özellikle paylaşımlı sunucularda disk kotanızın dolması, sitenizin çalışmasını durdurabilir. Bu yüzden erken uyarı almak işinizi kurtarır.
PHP Betiği Zaman Aşımını Yönetme
Uzun süren otomasyon işlemlerinde set_time_limit() fonksiyonu ile zaman aşımını kontrol edebilirsiniz. Örneğin, bir dosyayı işlerken genellikle 30 saniye yeterli olur, ancak büyük veri kümeleri için daha fazla süre gerekebilir:
set_time_limit(300); // 5 dakika
// Uzun süren işlem...
Eğer betiğiniz cron olarak çalışıyorsa, zaman aşımı genellikle sorun olmaz; ancak web üzerinden çalışan bir otomasyonunuz varsa bu ayarı değiştirmeniz gerekebilir. Ayrıca max_execution_time ayarını .htaccess veya php.ini üzerinden de değiştirebilirsiniz.
Sık Yapılan Hatalar ve Kaçınılması Gerekenler
Otomasyon kodları yazarken dikkat edilmesi gereken bazı noktalar var. Bunları kendi deneyimlerime ve yaygın sorunlara dayanarak derledim.
1. Hata Yönetimini Yetersiz Uygulamak
Otomasyon betikleri çoğu zaman gözden uzak çalışır. Bu nedenle hataları görmek için logları düzenli tutmalısınız. Basitçe error_log() ile hataları kaydetmek, sorunları çözmenize yardımcı olur. Ayrıca kritik görevlerde e-posta bildirimi eklemek iyi bir fikirdir.
2. Sabit Kodlanmış Bilgiler
Veritabanı şifreleri, API anahtarları ve dosya yollarını doğrudan kodun içine gömmek yerine bir yapılandırma dosyası veya ortam değişkenleri kullanın. Bu, güvenlik açısından da önemlidir.
3. Zamanlama Çakışmaları
Cron job’lar aynı anda iki kez çalışırsa, veri tutarsızlıklarına yol açabilir. Örneğin, bir dosyayı işleyen betik aynı anda iki kez başlarsa, dosyayı iki kez işleyebilir. Bunu önlemek için bir kilit mekanizması kullanabilirsiniz.
$lockFile = '/tmp/betik.lock';
if (file_exists($lockFile)) {
exit('Zaten çalışıyor.');
}
file_put_contents($lockFile, time());
// İşlemler...
unlink($lockFile);
Bu basit kilit yöntemi, aynı betiğin eşzamanlı çalışmasını engeller. Kilit dosyasını işlem sonunda silmeyi unutmayın; aksi halde sürekli kilitli kalabilir.
4. Zaman Dilimi ve Karakter Seti Sorunları
Otomasyon betiğinizin çalıştığı sunucunun zaman dilimi, veritabanı ve ayarlarınızla tutarlı olmalıdır. Aksi halde tarih hesapları yanlış olur. Benzer şekilde, Türkçe karakterleri doğru kullanmak için UTF-8 ayarlarını kontrol edin. Hem PHP’nin date_default_timezone_set() fonksiyonunu hem de veritabanı bağlantı sorgularında SET NAMES utf8 kullanmanızı öneririm.
Otomasyonunuzu Test Etme İpuçları
Otomasyon betiklerini canlıya almadan önce test etmeniz şarttır. Aşağıdaki adımlar, daha sağlam bir sistem kurmanıza yardımcı olacaktır:
- Betiği önce doğrudan komut satırından çalıştırın; hata mesajlarını anında görürsünüz.
- Cron ayarını kısa periyotlarla test edin, örn. her dakika. Sorunsuz çalıştığına emin olduktan sonra normal süreye çekin.
- Girdi verilerinde uç durumları test edin: boş klasör, olmayan dosya, hatalı API yanıtı.
- Log dosyanızı inceleyin; beklenmeyen çıktılar olup olmadığını kontrol edin.
Ayrıca, otomasyonu tetikleyen bir URL’yi tarayıcıdan ziyaret ederek de test edebilirsiniz. Ancak bu sayfayı başkalarının erişimine açık bırakmayın; basit bir parola koruması ekleyin.
Kendi Otomasyon Aracınızı Geliştirmek İçin Öneriler
Artık temel yapı taşlarını gördünüz. Sıra, kendi ihtiyacınıza uygun bir otomasyon sistemi tasarlamaya geldi. İşte size yol gösterici birkaç soru:
- Hangi süreçler tekrarlanıyor? Bu süreçlerin tanımını yapın.
- Bu süreçlerin hangileri zamanlanabilir? Hangileri gerçek zamanlı tetiklenmeli?
- Başarı ölçütünüz ne? Süre, hata oranı, maliyet?
- Hangi araçları kullanacaksınız? Saf PHP mi, hazır kütüphaneler mi, sunucu kaynakları mı?
Otomasyonun amacı, sizi tekrarlayan işlerden kurtararak daha değerli işlere zaman ayırmanızı sağlamaktır. Bu yüzden basit başlayın, küçük kazanımlar elde edin ve sistemi büyütün. Unutmayın, kusursuz bir otomasyon sistemi yoktur; sürekli iyileştirme gerekir. Bu yazıdaki örnekleri kendi projenize uyarlayarak başlayabilirsiniz.