Teknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor HaberleriTeknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor HaberleriTeknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor Haberleri
Yazı Tipi BoyutlandırıcıAa
  • Anasayfa
  • Teknoloji
    • Siber Güvenlik
    • Yapay Zeka
    • Donanım
    • Bilim
  • Yazılım
  • Savunma & İstihbarat
  • Oyun
  • Yaşam
    • Finans
    • Sinema
    • Dünyadan Haberler
  • İş Birliği
Okuma: Web Uygulamasından Yazdırma Diyalogu Olmadan Doğrudan Termal Yazdırma (PHP/Laravel)
Paylaş
Yazı Tipi BoyutlandırıcıAa
Teknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor HaberleriTeknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor Haberleri
Ara
Bizi Takip Et
  • Hakkımızda
  • Gizlilik politikası
  • Tanıtım Yazısı ve Backlink Hizmeti
© 2026 Teknomers. All Rights Reserved.

Anasayfa » Web Uygulamasından Yazdırma Diyalogu Olmadan Doğrudan Termal Yazdırma (PHP/Laravel)

Yazılım

Web Uygulamasından Yazdırma Diyalogu Olmadan Doğrudan Termal Yazdırma (PHP/Laravel)

teknomers
Son güncelleme: 22 Ocak 2026 03:07
teknomers
Paylaş
Paylaş

Web tabanlı bir Satış Noktası (POS) sistemi geliştirmek, en büyük sıkıntılardan birini getirir: Yazdırma.

<p>Eğer daha önce bir web tabanlı fatura uygulaması geliştirdiyseniz, o süreci bilirsiniz. `window.print()` çağrısı yaparsınız, tarayıcı bir yazdırma diyalogu açar, kullanıcı yazıcıyı seçmek zorundadır, belki de kenar boşluklarını ayarlayıp sonunda "Yazdır" tuşuna basar.</p>

<p>Yoğun bir perakende kasiyeri için, her işlemdeki 5 saniyelik gecikme kabul edilemez.</p>

<p>Ben yakın zamanda PagoraPOS adlı bir TALL stack (Tailwind, Alpine, Laravel, Livewire) POS sistemi geliştirdim. Amacım, bunu yerel bir masaüstü uygulaması gibi hissettirmekti. Bu da demek oluyor ki, yazdırma işlemi anlık, sessiz ve termal kağıtta piksel mükemmelliğinde olmalıydı.</p>

<p>İşte bu "Web'den Termal Yazıcıya" zorluğunu PHP kullanarak, tarayıcı diyalogunu tamamen atlayarak nasıl çözdüm.</p>

<p><strong>window.print() ile İlgili Problemler</strong><br/>Standart tarayıcı yazdırması, CSS'e dayanır. Bir sayfayı fatura gibi görünmesi için şekillendirebilirsiniz (genişlik: 80mm), fakat hızla sınırlamaların farkına varırsınız.</p>

<p><strong>Çözüm: Raw ESC/POS Komutları</strong><br/>Termal yazıcılar (Epson, Star, Xprinter) "ESC/POS" adında bir ham dilde konuşurlar. Bir HTML resmi göndermek yerine, hex komutları gönderirsiniz.</p>

<p>Örneğin, `x1B\x40` komutu yazıcıyı başlatır. `x1D\x56\x42\x00` komutu ise kağıdı keser.</p>

<p>PHP ekosisteminde, bu işlemi gerçekleştiren en iyi kütüphane mike42/escpos-php'dir.</p>

<p><strong>&gt; Adım 1: Kurulum</strong><br/>Önce, Laravel projemde kütüphaneyi kurdum:<br/></p>

<div class="highlight js-code-highlight">
    <pre class="highlight plaintext"><code>composer require mike42/escpos-php

<p><strong>&gt; Adım 2: Sunucuda Faturanın Oluşturulması</strong><br/>Bir Blade görünümü render etmek yerine, yazdırma komutlarını oluşturmaktan sorumlu bir Servis Sınıfı oluşturdum.</p>

<p>İşte basitleştirilmiş PrinterService'im:<br/></p>

<div class="highlight js-code-highlight">
    <pre class="highlight php"><code><span class="kn">use</span> <span class="nc">Mike42\Escpos\Printer</span><span class="p">;</span>

use Mike42\Escpos\PrintConnectors\NetworkPrintConnector;
use Mike42\Escpos\CapabilityProfile;

class ThermalPrintService
{
public function printReceipt($transaction)
{
// 1. Yazıcıya bağlan (örneğin, LAN’daki Ağ Yazıcısı)
// Gerçek uygulamada, bu IP veritabanı ayarlarından gelir
$connector = new NetworkPrintConnector(“192.168.1.87”, 9100);

    <span class="c1">// 2. Profilleri yükle (Epson/Star gibi belirli markalar için optimize eder)</span>
    <span class="nv">$profile</span> <span class="o">=</span> <span class="nc">CapabilityProfile</span><span class="o">::</span><span class="nf">load</span><span class="p">(</span><span class="s2">"default"</span><span class="p">);</span>

    <span class="c1">// 3. Yazıcıyı başlat</span>
    <span class="nv">$printer</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Printer</span><span class="p">(</span><span class="nv">$connector</span><span class="p">,</span> <span class="nv">$profile</span><span class="p">);</span>

    <span class="k">try</span> <span class="p">{</span>
        <span class="c1">// --- BAŞLIK ---</span>
        <span class="nv">$printer</span><span class="o">-&gt;</span><span class="nf">setJustification</span><span class="p">(</span><span class="nc">Printer</span><span class="o">::</span><span class="no">JUSTIFY_CENTER</span><span class="p">);</span>
        <span class="nv">$printer</span><span class="o">-&gt;</span><span class="nf">selectPrintMode</span><span class="p">(</span><span class="nc">Printer</span><span class="o">::</span><span class="no">MODE_DOUBLE_WIDTH</span> <span class="o">|</span> <span class="nc">Printer</span><span class="o">::</span><span class="no">MODE_BOLD</span><span class="p">);</span>
        <span class="nv">$printer</span><span class="o">-&gt;</span><span class="nf">text</span><span class="p">(</span><span class="s2">"PAGORA STORE</span><span class="se">\n</span><span class="s2">"</span><span class="p">);</span>
        <span class="nv">$printer</span><span class="o">-&gt;</span><span class="nf">selectPrintMode</span><span class="p">();</span> <span class="c1">// Sıfırla</span>
        <span class="nv">$printer</span><span class="o">-&gt;</span><span class="nf">text</span><span class="p">(</span><span class="s2">"123 Laravel Blvd, Code City</span><span class="se">\n</span><span class="s2">"</span><span class="p">);</span>
        <span class="nv">$printer</span><span class="o">-&gt;</span><span class="nf">feed</span><span class="p">();</span>

        <span class="c1">// --- ÜRÜNLER ---</span>
        <span class="nv">$printer</span><span class="o">-&gt;</span><span class="nf">setJustification</span><span class="p">(</span><span class="nc">Printer</span><span class="o">::</span><span class="no">JUSTIFY_LEFT</span><span class="p">);</span>
        <span class="nv">$printer</span><span class="o">-&gt;</span><span class="nf">text</span><span class="p">(</span><span class="s2">"--------------------------------</span><span class="se">\n</span><span class="s2">"</span><span class="p">);</span>

        <span class="k">foreach</span> <span class="p">(</span><span class="nv">$transaction</span><span class="o">-&gt;</span><span class="n">items</span> <span class="k">as</span> <span class="nv">$item</span><span class="p">)</span> <span class="p">{</span>
            <span class="c1">// Metni hizalamak için yardımcı fonksiyon</span>
            <span class="nv">$line</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">formatRow</span><span class="p">(</span><span class="nv">$item</span><span class="o">-&gt;</span><span class="n">name</span><span class="p">,</span> <span class="nv">$item</span><span class="o">-&gt;</span><span class="n">qty</span> <span class="mf">.</span> <span class="s1">'x '</span> <span class="mf">.</span> <span class="nv">$item</span><span class="o">-&gt;</span><span class="n">price</span><span class="p">);</span>
            <span class="nv">$printer</span><span class="o">-&gt;</span><span class="nf">text</span><span class="p">(</span><span class="nv">$line</span> <span class="mf">.</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">);</span>
        <span class="p">}</span>

        <span class="nv">$printer</span><span class="o">-&gt;</span><span class="nf">text</span><span class="p">(</span><span class="s2">"--------------------------------</span><span class="se">\n</span><span class="s2">"</span><span class="p">);</span>

        <span class="c1">// --- TOPLAM ---</span>
        <span class="nv">$printer</span><span class="o">-&gt;</span><span class="nf">setJustification</span><span class="p">(</span><span class="nc">Printer</span><span class="o">::</span><span class="no">JUSTIFY_RIGHT</span><span class="p">);</span>
        <span class="nv">$printer</span><span class="o">-&gt;</span><span class="nf">setEmphasis</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
        <span class="nv">$printer</span><span class="o">-&gt;</span><span class="nf">text</span><span class="p">(</span><span class="s2">"TOPLAM: $"</span> <span class="mf">.</span> <span class="nv">$transaction</span><span class="o">-&gt;</span><span class="n">total</span> <span class="mf">.</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">);</span>
        <span class="nv">$printer</span><span class="o">-&gt;</span><span class="nf">setEmphasis</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
        <span class="nv">$printer</span><span class="o">-&gt;</span><span class="nf">feed</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span>

        <span class="c1">// --- DONANIM FONKSİYONLARI ---</span>
        <span class="nv">$printer</span><span class="o">-&gt;</span><span class="nf">cut</span><span class="p">();</span> <span class="c1">// Kağıdı kes</span>
        <span class="nv">$printer</span><span class="o">-&gt;</span><span class="nf">pulse</span><span class="p">();</span> <span class="c1">// Nakit çekmecesini aç (Kick)</span>

    <span class="p">}</span> <span class="k">finally</span> <span class="p">{</span>
        <span class="nv">$printer</span><span class="o">-&gt;</span><span class="nf">close</span><span class="p">();</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">private</span> <span class="k">function</span> <span class="n">formatRow</span><span class="p">(</span><span class="nv">$left</span><span class="p">,</span> <span class="nv">$right</span><span class="p">,</span> <span class="nv">$width</span> <span class="o">=</span> <span class="mi">32</span><span class="p">)</span>
<span class="p">{</span>
    <span class="c1">// "Ürün Adı ...... $10.00" düzenini oluşturmak için basit bir mantık</span>
    <span class="nv">$len</span> <span class="o">=</span> <span class="nv">$width</span> <span class="o">-</span> <span class="nb">strlen</span><span class="p">(</span><span class="nv">$right</span><span class="p">);</span>
    <span class="k">return</span> <span class="nb">str_pad</span><span class="p">(</span><span class="nb">substr</span><span class="p">(</span><span class="nv">$left</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nv">$len</span><span class="p">),</span> <span class="nv">$len</span><span class="p">)</span> <span class="mf">.</span> <span class="nv">$right</span><span class="p">;</span>
<span class="p">}</span>

}

<p><strong>&gt; Adım 3: Sunucu ve Yazıcı Arasındaki Köprü</strong><br/>Burada işler karmaşıklaşıyor. PHP sunucuda çalışıyor, ancak yazıcı müşterinin dükkanında.</p>

<p>PagoraPOS'ta bunu dağıtıma göre iki şekilde yönetiyorum:</p>

<p><strong>Senaryo A</strong>: Kendine Ait / Yerel Sunucu Eğer müşteri uygulamayı yerel bir sunucuda (örneğin, dükkandaki Mini PC) çalıştırıyorsa, PHP yazıcının IP adresiyle doğrudan iletişim kurabilir (yukarıdaki kod gibi). Hız son derece yüksektir.</p>

<p><strong>Senaryo B</strong>: Bulut Sunucu (SaaS) Eğer uygulama bulutta (AWS/DigitalOcean) barındırılmışsa, PHP `192.168.1.x` adresine ulaşamaz. Bunun için, yazdırma komutunu PHP'de yürütmek yerine, ESC/POS komutlarının Raw Base64 verisini oluşturuyorum ve frontend'e geri gönderiyorum (Alpine.js kullanarak).</p>

<p>Frontend, bu ham veriyi kasiyerin bilgisayarında çalışan küçük bir "Yazdırma Proxy" ajansına gönderiyor (veya QZ Tray gibi bir kütüphane kullanabiliyor) ve veriyi USB/Ağ yazıcısına iletiyor.</p>

<p>Bu yaklaşımın avantajları:</p>
<ul>
    <li>Hız: HTML render etme ve Chrome'un bekleme süresi yok.</li>
    <li>Kontrol: Nakit ödeme yapıldığında otomatik olarak Nakit Çekmecesini açabiliyorum.</li>
    <li>Tutarlılık: Fatura, tarayıcı veya işletim sisteminden bağımsız olarak tam olarak aynı görünüyor.</li>
</ul>

<p><strong>Sonuç</strong><br/>Laravel ile bir POS uygulaması inşa etmek ilginç bir yolculuk oldu. Filament V3 gibi çerçeveler UI için harika olsa da, yazılım mimarisinin derinliklerine inmeye ve ESC/POS gibi düşük seviyeli donanım iletişimine dalmak, uygulamanın son kullanıcılar için "profesyonel" hissettirmesini sağlıyor.</p>

<p>Eğer bir perakende uygulaması geliştiriyorsanız, tarayıcı yazdırma diyalogunu atlamanızı şiddetle tavsiye ederim. Kullanıcılarınız bunu takdir edecektir.</p>

<p>Şu anda bu sistemi PagoraPOS projemde geliştirmeye devam ediyorum. Ham yazdırma veya POS için TALL stack yapısı hakkında sorularınız varsa, aşağıda yorum bırakabilirsiniz!</p>

Kaynak: Orijinal Makale

  1. Gün: Neredeyse Her Şeyi Aşırı Mühendislik Yaptım
Laravel Politikaları: Yetkilendirmeyi Merkezi Hale Getirin ve Kontrolcülerinizin Temiz Kalmasını Sağlayın
Laravel Yanıt Önbelleği Yanlış Dili Sunuyor: spatie/laravel-responsecache’i mcamara/laravel-localization ile Düzeltme
Laravel SaaS’im için Spatie Kullanmadan Tam Bir Çoklu Kiracı Sistemi Nasıl Geliştirdim
Laravel’de Monolit Kullanımı – DEV Community
Bu Makaleyi Paylaş
Facebook Bağlantıyı Kopyala Yazdır
Paylaş
Önceki Makale Apple, Siri’yi AI sohbet botuna dönüştürmeyi planlıyor
Sonraki Makale TV’nizden Sesleri Kulaklıkla Duyabilirsiniz: Bu Vericiyle Mümkün

Sanal Medya

FacebookBeğen
452Takip Et
PinterestSabitle
237Takip Et

Son Eklenenler

Şimşek, coaxial kablodan apartmana girip PC’yi patlattı
Donanım
Outlook’un yıllardır güvenlik açığı, Fedora ve Dovecot güncellemesiyle ortaya çıktı
Donanım
Yaz Geliştirici Festivali 2026: Tüm Yenilikler Ortaya Çıkıyor
Oyun
Madonna’nın Grindr’daki Cesur ve Heyecan Verici Ticareti
Genel
Meta’nın AI Sunucuları İçin Tüm ABD’ye Çadırlar Kurması
Donanım
Grand Theft Auto VI Oyun Dünyasında Tarihleri Değiştiriyor
Liste
//

Siber güvenlik, yapay zeka ve savunma sanayiinden; finans ve sinema dünyasına uzanan geniş bir yelpaze. Teknomers; teknoloji, strateji ve yazılım dünyasını sade bir dille sizlerle buluşturuyor.

Kurumsal

  • Hakkımızda
  • Gizlilik politikası
  • Tanıtım Yazısı ve Backlink Hizmeti

Kategoriler

  • Teknoloji
  • Oyun
  • Sinema
  • Siber Güvenlik
  • Bilim
  • Finans
  • Dünyadan Güncel Haberler

Populer

  • TV'de Ücretsiz İzlenebilen Şifresiz Erotik Kanallar (2025 Güncel Frekans Listesi)

  • The Last of Us PC Kontrolleri: Hızlı Silah Değiştirme ve Tüm Tuşlar (2025)

  • Hogwarts Legacy'de Odaklanma İksiri Nasıl Yapılır?

Teknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor HaberleriTeknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor Haberleri
Bizi Takip Et
© 2026 Teknomers. All Rights Reserved.
Welcome Back!

Sign in to your account

Kullanıcı Adı veya E-posta Adresi
Şifre

Şifrenizi mi unuttunuz?