Php ile başka bir web sitesinden tabloları kopyalamak nasıl?

3 Cevap php

Ben 2 web siteleri var, diyelim - example.com ve example1.com

example.com apple 7000 kayıtlarında bir tablo var fruits bir veritabanına sahiptir.

Ben ihraç apple ve example1.com içe çalıştı ama ben hep "MYSQL Server has gone away" hata alıyorum. Ben bu bazı sunucu tarafı kısıtlama nedeniyle şüpheleniyoruz.

Yani, nasıl sistem yöneticilerden temasa gerek kalmadan tabloları kopyalamak? PHP kullanarak bunu yapmanın bir yolu var mı? Ben tabloları kopyalama Örneğin geçti, ama bu aynı veritabanı içinde oldu.

Hem example.com ve example1.com aynı sunucu üzerinde bulunmaktadır.

3 Cevap

Bir süre için, bu mücadele sonrasında geldi BigDump. Bu bir cazibe gibi çalıştı! Bir aksaklık olmadan BÜYÜK veritabanlarını kopyalamak mümkün oldu.

Olası bir yaklaşım:

  1. "Kaynak" sunucuda (XML oluşturmak ve tüketmek kolay olarak akla geliyor, ama CSV gibi alternatifler yapabileceği) biçiminde ayrıştırmak için kolay bir tablonun içeriğini çıktılar bir PHP komut dosyası ("ihracatçı") oluşturabilirsiniz.

  2. "Hedef" sunucuda, HTTP üzerinden ihracatçısı bir istekleri sonucu ayrıştırır ve veri tablo doldurmak için kullanan bir "ithalatçı" PHP komut dosyası oluşturun.

Bu oldukça genel, ama başlamak gerekir. İşte bazı hususlar şunlardır:

  • http://ie2.php.net/manual/en/function.http-request.php arkadaşınız
  • Tablo hassas verileri içeriyorsa, orada (http_request doğrudan size https:// destek vermeyecektir güvenliğini artırmak için birçok teknik vardır, ama dışa verileri şifrelemek ve ithal şifresini çözebilir: PHP kılavuzda "SSL" için bakın Daha fazla bilgi için).
  • Bunu sunucular arasındaki ağ yelken yaparken tahrif olmaktan veri önlemek için bazı fazlalık (hatta tam tenli şifreleme) eklemeyi düşünmelisiniz.
  • Sen (siz hiç aktarmak gerekebilir tüm tablolar için tek bir komut dosyası var sağlayacak bir parametre olarak tablo adı geçen, örneğin) esneklik eklemek için GET parametreleri kullanabilirsiniz.
  • Büyük tablolar, PHP zaman aşımı size karşı oynayabilir. Bunun için ideal bir çözüm verimli kod + ihracat ve ithalat komut için özel bir zaman aşımı olurdu, ama ben bu hiç mümkün bile emin değilim. Oldukça güvenilir bir geçici çözüm (params ne gerek duyulur ihracatçı anlatmak için kullanışlı buraya gelip GET ve çıkışında özel bir giriş ithalat bırakılır ne kadar ileti anlatmak için yeterli olabilir) parçalar işi yapmaktır. (Zaman aşımı reset olsun böylece her yönlendirme, sunuculara, yeni bir istek), bu yaklaşımı ile bir çok yardımcı yönlendirir.

Belki de ben bir şey eksik, ama iş kirli ellerin ve ben görmekte başarısız olabilir herhangi bir özel konu ile geri gelmesine izin orada yeterli olduğunu umuyoruz.

Umarım bu yardımcı olur.


EDIT: Oops, I missed the detail that both DBs are on the same server. In that case, you can merge the import and export task into a single script. This means that:

  • (Örneğin, XML veya CSV olarak) bir "transfer" biçimini gerekmez: şimdi hem görevleri aynı komut dosyası içinde yapılır beri içinde PHP bellek temsil yeterlidir.
  • Veri hiç sunucu bırakmaz, bu yüzden şifreleme için ihtiyaç kadar ağır değildir. Sadece emin hiç kimse (kimlik veya benzer tekniklerle üzerinden) komut çalıştırabilirsiniz yapmak ve ince olmalıdır.
  • Eğer yanıt hedef sunucuya kaynağından gelmesi için bekleyen çok fazla zaman kaybetmeyin beri zaman aşımları, o kadar kısıtlayıcı değildir, ama onlar hala geçerli. Chunk işleme, yönlendirme, ve (yönlendirme için konumu içinde geçti) parametreleri hala iyi bir çözüm, ama çapraz sunucu veri transferi ölçümleri çok daha güvenilir yürütme zamanı ölçümleri beri aşımı çok yakın sıkmak olabilir GET.

Burada koduna sahip olabilecek ne bir very rough sketch :

$link_src = mysql_connect(source DB connection details);
$link_dst = mysql_connect(destination DB connection details);
/* You may want to truncate the table on destination before going on, to prevent data repetition */
$q = "INSERT INTO `table_name_here` (column_list_here) VALUES ";
$res = mysql_query("SELECT * FROM `table_name_here`", $link_src);
while ($row = mysql_fetch_assoc($res)) {
    $q = $q . sprintf("(%s, %s, %s), ", $row['field1_name'], $row['field2_name'], $row['field3_name']);
}
mysql_free_result($res);
/* removing the trailing ',' from $q is left as an exercise (ok, I'm lazy, but that's supposed to be just a sketck) */
mysql_query($q, $link_dst);

You'll have to add the chunking logics in there (those are too case- & setup- specific), and probably output some confirmation message (maybe a DESCRIBE and a COUNT of both source and destination tables and a comparison between them?), but that's quite the core of the job. As an alternative you may run a separate insert per row (invoking the query within the loop), but I'm confident a single query would be faster (however, if you have too small RAM limits for PHP, this alternative allows you to get rid of the memory-hungry $q).


Yine başka bir düzenleme:

Roberto tarafından yayınlanan belgeler link:

Eğer yanlış ya da çok büyük sunucusuna bir sorgu gönderirseniz bu hatalar da alabilirsiniz. Mysqld çok büyük veya bozuk olan bir paket alırsa, bir şey müşteri ile yanlış gitti varsayar ve bağlantıyı kapatır. (Eğer büyük BLOB sütunları ile çalışıyorsanız örneğin) büyük sorguları gerekiyorsa, 1MB bir varsayılan değere sahiptir sunucunun max_allowed_packet değişken ayarlayarak sorgu sınırını artırabilirsiniz. Ayrıca istemci ucunda maksimum paket boyutunu artırmak gerekebilir. Paket boyutunu ayarlama hakkında daha fazla bilgi "Paket çok büyük", Bölüm B.5.2.10 verilmiştir.

Pek çok satır ekler bir INSERT veya bildirimde DEĞİŞTİR de hataları bu türlü neden olabilir. Bu ifadelerin ya bir eklenecek satır sayısı ne olursa olsun sunucuya tek bir isteği gönderir; Böylece, sık sık INSERT başına veya DEĞİŞTİR gönderilen satır sayısını azaltarak hatayı önleyebilirsiniz.

Lütfen sorununuzu neden buydu (ve soruya göre bu o very olası görünüyor), sonra satır başına bir sorgu içine INSERT kırma yaklaşımı muhtemelen bunu çözecektir. Bu durumda, yukarıdaki kodu kroki olur:

$link_src = mysql_connect(source DB connection details);
$link_dst = mysql_connect(destination DB connection details);
/* You may want to truncate the table on destination before going on, to prevent data repetition */
$q = "INSERT INTO `table_name_here` (column_list_here) VALUES ";
$res = mysql_query("SELECT * FROM `table_name_here`", $link_src);
while ($row = mysql_fetch_assoc($res)) {
    $q = $q . sprintf("INSERT INTO `table_name_here` (`field1_name`, `field2_name`, `field3_name`) VALUE (%s, %s, %s)", $row['field1_name'], $row['field2_name'], $row['field3_name']);
}
mysql_free_result($res);

Sorun da ilk SELECT büyük hacim tarafından tetiklenebilir; Böyle durumda parçalama ile birleştirmek gerekir (ya da birden fazla SELECT + ile while () blokları, SQL'ın LİMİT maddesi, ya da yönlendirmeler aracılığıyla kar alarak) bu şekilde birden fazla, küçük sorguları içine SELECT kırma. (Note that redirection-based chunking is only needed if you have timeout issues, or your execution time gets close enough to the timeout to threaten with issues if the table grows. It may be a good idea to implement it anyway, so even if your table ever grows to an obscene size the script will still work unchanged.)

İşte MySQL 5.0 "MySQL Server uzağa gitti" hata en yaygın nedenleri bildirilmiştir:

http://dev.mysql.com/doc/refman/5.0/en/gone-away.html

Sen ona bir göz atmak ve yanlış bir şey yaptığınızı görmek için bir kontrol listesi olarak kullanmak isteyebilirsiniz.