Tentang kinerja (buang-buang waktu dengan optimasi mikro seperti saya), lihat jawaban ini : constdua kali lebih cepat daripada define. Tentang waktu buka halaman dan penggunaan memori: lihat pertanyaan ini dan artikel ini ... Lihat juga sesuatu tentang cache opcode di sini .
Peter Krauss
2
Jangan hanya melihat jawaban yang diterima saat ini, tetapi silakan lihat ke stackoverflow.com/a/3193704/1412157 karena seharusnya jawaban yang diterima
LucaM
1
Baru saja melihat pemberitahuan untuk komentar Anda. Saya telah memperbarui jawaban yang diterima.
Perbedaan mendasar antara kedua cara tersebut adalah bahwa constmendefinisikan konstanta pada waktu kompilasi, sedangkan definemendefinisikannya pada saat run time. Ini menyebabkan sebagian besar constkerugian. Beberapa kelemahan constadalah:
consttidak dapat digunakan untuk mendefinisikan konstanta secara kondisional. Untuk mendefinisikan konstanta global, ia harus digunakan dalam lingkup terluar:
Mengapa Anda tetap ingin melakukan itu? Satu aplikasi umum adalah untuk memeriksa apakah konstanta sudah ditentukan:
if(!defined('FOO')){
define('FOO','BAR');}
constmenerima skalar statis (nomor, string atau konstan lain seperti true, false, null, __FILE__), sedangkan define()mengambil ekspresi apapun. Karena PHP 5.6 ekspresi konstan juga diperbolehkan const:
const BIT_5 =1<<5;// Valid since PHP 5.6 and invalid previously
define('BIT_5',1<<5);// Always valid
constmengambil nama konstan polos, sedangkan define()menerima ekspresi apa pun sebagai nama. Ini memungkinkan untuk melakukan hal-hal seperti ini:
consts selalu peka huruf besar kecil, sedangkan define()memungkinkan Anda untuk mendefinisikan konstanta tidak peka huruf besar kecil dengan melewatkan truesebagai argumen ketiga (Catatan: mendefinisikan konstanta peka-huruf tidak berlaku lagi pada PHP 7.3.0.):
define('FOO','BAR',true);
echo FOO;// BAR
echo foo;// BAR
Jadi, itulah sisi buruknya. Sekarang mari kita lihat alasan mengapa saya selalu menggunakan constkecuali jika salah satu dari situasi di atas terjadi:
consthanya membaca lebih baik. Ini adalah konstruksi bahasa alih-alih fungsi dan juga konsisten dengan cara Anda mendefinisikan konstanta di kelas.
const, sebagai konstruksi bahasa, dapat dianalisis secara statis dengan perkakas otomatis.
constmendefinisikan konstanta di namespace saat ini, sementara define()harus melewati nama namespace lengkap:
namespace A\B\C;// To define the constant A\B\C\FOO:const FOO ='BAR';
define('A\B\C\FOO','BAR');
Karena constkonstanta PHP 5.6 juga bisa berupa array, sementara define()itu belum mendukung array. Namun, array akan didukung untuk kedua kasus di PHP 7.
const FOO =[1,2,3];// Valid in PHP 5.6
define('FOO',[1,2,3]);// Invalid in PHP 5.6 and valid in PHP 7.0
Akhirnya, perhatikan bahwa constjuga dapat digunakan dalam kelas atau antarmuka untuk menentukan konstanta kelas atau antarmuka konstan. definetidak dapat digunakan untuk tujuan ini:
classFoo{const BAR =2;// Valid}// ButclassBaz{
define('QUX',2);// Invalid}
Ringkasan
Kecuali jika Anda memerlukan jenis definisi kondisional atau ekspresi, gunakan consts alih-alih define()s - hanya demi keterbacaan!
Seperti yang saya tahu dengan PHP 5.6 Anda akan mendapatkan kemungkinan untuk menggunakan ekspresi skalar sederhana bahkan dengan constkonstruksi bahasa - lihat wiki.php.net/rfc/const_scalar_exprs
mabe.berlin
6
Manfaat lain untuk menggunakan constadalah kurangnya tanda kutip, artinya diformat sama dengan yang digunakan dalam IDE Anda.
rybo111
3
Ini harus menjadi apa yang ada dalam dokumen PHP. Ini penjelasan terbaik yang pernah saya lihat, terutama bagian yang kebanyakan orang lupa (kompilasi vs runtime).
James
4
define('a', $_GET['param']);, const b = a;bekerja dengan sempurna dan mendapatkan nilai saat const c = $_GET['param'];tidak valid Apakah constwaktu kompilasi benar-benar? Saya kira tidak begitu ... (diuji pada PHP 7.0.7)
Hingga PHP 5.3, consttidak bisa digunakan dalam lingkup global. Anda hanya bisa menggunakan ini dari dalam kelas. Ini harus digunakan ketika Anda ingin mengatur semacam opsi atau pengaturan konstan yang berkaitan dengan kelas itu. Atau mungkin Anda ingin membuat semacam enum.
definedapat digunakan untuk tujuan yang sama, tetapi hanya dapat digunakan dalam lingkup global. Seharusnya hanya digunakan untuk pengaturan global yang mempengaruhi seluruh aplikasi.
Contoh constpenggunaan yang baik adalah untuk menghilangkan angka ajaib. Lihatlah konstanta PDO . Ketika Anda perlu menentukan jenis pengambilan, Anda akan mengetik PDO::FETCH_ASSOC, misalnya. Jika const tidak digunakan, Anda akan mengetik sesuatu seperti 35(atau apa pun FETCH_ASSOCyang didefinisikan sebagai). Ini tidak masuk akal bagi pembaca.
Contoh definepenggunaan yang baik mungkin menentukan jalur akar aplikasi Anda atau nomor versi pustaka.
Mungkin layak menyebutkan penggunaan constdengan ruang nama.
salathe
31
Juga harus dicatat bahwa PHP5.3 dapat menggunakan const dalam lingkup global.
Gordon
5.2 juga bisa. Keindahan consts vs mendefinisikan adalah bahwa Anda harus mengawali mereka dengan nama kelas. Menggunakannya membuat kode lebih mudah dibaca dan lebih cantik. Dan itu bonus bagi saya.
Luar biasa
1
@ryeguy tetapi bagaimana dengan setelah PHP 5.3 dimana const dapat digunakan secara global seperti define?
andho
1
@ andho, buat yang lain ke tarian PHP satu langkah maju, satu langkah mundur, tarian "perbaikan". Dia. :)
Kontrak Prof. Falken dilanggar
37
Saya tahu ini sudah dijawab, tetapi tidak ada jawaban saat ini yang menyebutkan namespacing dan bagaimana pengaruhnya terhadap konstanta dan definisi.
Pada PHP 5.3, konstanta dan definisi hampir sama dalam banyak hal. Namun, masih ada beberapa perbedaan penting:
Konstanta tidak dapat didefinisikan dari ekspresi. const FOO = 4 * 3;tidak bekerja, tetapi define('CONST', 4 * 3);tidak.
Nama yang diteruskan defineharus menyertakan namespace yang akan didefinisikan dalam namespace itu.
Kode di bawah ini harus menggambarkan perbedaan.
namespace foo
{const BAR =1;
define('BAZ',2);
define(__NAMESPACE__ .'\\BAZ',3);}namespace{
var_dump(get_defined_constants(true));}
Konten dari sub-array pengguna akan ['foo\\BAR' => 1, 'BAZ' => 2, 'foo\\BAZ' => 3].
=== UPDATE ===
PHP 5.6 mendatang akan memungkinkan fleksibilitas yang lebih tinggi dengan const. Anda sekarang dapat mendefinisikan const dalam hal ekspresi, asalkan ekspresi tersebut terdiri dari const lain atau literal. Ini berarti yang berikut ini harus valid pada 5.6:
const FOOBAR ='foo '.'bar';const FORTY_TWO =6*9;// For future editors: THIS IS DELIBERATE! Read the answer comments below for more detailsconst ULTIMATE_ANSWER ='The ultimate answer to life, the universe and everything is '. FORTY_TWO;
Anda masih tidak akan dapat mendefinisikan const dalam hal variabel atau fungsi kembali, jadi
Saya tidak bisa menahan diri untuk bertanya: Apakah Anda secara sadar mendefinisikan FORTY_TWOsebagai 54?
Punchlinern
9
"Enam kali sembilan? Empat puluh dua? Saya selalu mengatakan ada sesuatu yang secara fundamental salah dengan alam semesta" Periksa karya-karya Douglas Adams jika Anda membutuhkan penjelasan lengkap.
GordonM
2
Oh Saya sadar bahwa 42 adalah jawaban kehidupan, alam semesta, dan segalanya kecuali sembilan bagian yang saya lewatkan. Terima kasih untuk penjelasannya!
Punchlinern
22
Saya percaya bahwa pada PHP 5.3, Anda dapat menggunakan di constluar kelas, seperti yang ditunjukkan di sini dalam contoh kedua:
Anda tidak bisa definemasuk ke dalam ruang lingkup kelas, dan dengan constAnda bisa. Tidak perlu dikatakan, Anda tidak dapat menggunakan construang lingkup kelas luar.
Juga, dengan const, itu benar-benar menjadi anggota kelas, dan dengan define, itu akan didorong ke ruang lingkup global.
Seperti disebutkan dalam jawaban lain, const dapat digunakan di luar kelas di PHP 5.3+
MrWhite
Hanya kata kunci const yang dapat digunakan untuk membuat konstanta dengan spasi nama, tidak hanya kelas
Alireza Rahmani Khalili
16
Jawaban NikiC adalah yang terbaik, tetapi izinkan saya menambahkan peringatan yang tidak jelas ketika menggunakan ruang nama sehingga Anda tidak terjebak dengan perilaku yang tidak terduga. Yang perlu diingat adalah bahwa definisi selalu di namespace global kecuali jika Anda secara eksplisit menambahkan namespace sebagai bagian dari pengidentifikasi define. Apa yang tidak jelas tentang itu adalah bahwa pengidentifikasi namespaced mengalahkan pengidentifikasi global. Jadi:
<?php
namespace foo
{// Note: when referenced in this file or namespace, the const masks the defined version// this may not be what you want/expectconst BAR ='cheers';
define('BAR','wonka');
printf("What kind of bar is a %s bar?\n", BAR);// To get to the define in the global namespace you need to explicitely reference it
printf("What kind of bar is a %s bar?\n", \BAR);}namespace foo2
{// But now in another namespace (like in the default) the same syntax calls up the // the defined version!
printf("Willy %s\n", BAR);
printf("three %s\n", \foo\BAR);}?>
menghasilkan:
What kind of bar is a cheers bar?What kind of bar is a wonka bar?
willy wonka
three cheers
Yang bagi saya membuat seluruh gagasan const tidak perlu membingungkan karena ide tentang const dalam lusinan bahasa lain adalah bahwa itu selalu sama di mana pun Anda berada dalam kode Anda, dan PHP tidak benar-benar menjamin itu.
Yeah, tapi BARdan \foo\BARhanya tidak konstanta yang sama. Saya setuju itu benar-benar membingungkan, tetapi jika Anda juga menganggap hal-hal seperti logika namespacing konsisten dengan cara ini, dan tidak constjuga define()tidak seperti makro C ( #define), maka PHP dapat memiliki beberapa alasan.
Sz.
1
Gagasan const persis seperti seharusnya berperilaku - Anda berada di namespace! Anda menginginkannya tanpa pengidentifikasi namespace, kemudian membuatnya di luar namespace .. Ini juga membuatnya konsisten dengan konst yang didefinisikan dalam kelas, bahkan jika menggunakan sintaks yang berbeda. Ya, define juga konsisten, dengan cara yang berbeda.
Gerard ONeill
12
Sebagian besar jawaban ini salah atau hanya menceritakan setengah dari cerita.
Anda dapat menetapkan konstanta dengan menggunakan ruang nama.
Anda dapat menggunakan kata kunci "const" di luar definisi kelas. Namun, seperti di kelas, nilai yang diberikan menggunakan kata kunci "const" harus berupa ekspresi konstan.
PHP> = 5.6 beberapa perubahan telah dibuat di Zend Engine Compiler dan const sedang diperlakukan dengan cara lain sekarang.
Ankit Vishwakarma
6
Ya, const didefinisikan pada waktu kompilasi dan karena status nikic tidak dapat diberikan ekspresi, seperti yang dapat didefinisikan () dapat. Tetapi juga const tidak dapat dinyatakan secara kondisional (untuk alasan yang sama). yaitu. Anda tidak dapat melakukan ini:
if(/* some condition */){const WHIZZ =true;// CANNOT DO THIS!}
Sedangkan Anda bisa dengan define (). Jadi, itu tidak benar-benar turun ke preferensi pribadi, ada cara yang benar dan salah untuk menggunakan keduanya.
Sebagai tambahan ... Saya ingin melihat semacam konst kelas yang dapat diberi ekspresi, semacam define () yang dapat diisolasi ke kelas?
const
dua kali lebih cepat daripadadefine
. Tentang waktu buka halaman dan penggunaan memori: lihat pertanyaan ini dan artikel ini ... Lihat juga sesuatu tentang cache opcode di sini .Jawaban:
Pada PHP 5.3 ada dua cara untuk mendefinisikan konstanta : Entah menggunakan
const
kata kunci atau menggunakandefine()
fungsi:Perbedaan mendasar antara kedua cara tersebut adalah bahwa
const
mendefinisikan konstanta pada waktu kompilasi, sedangkandefine
mendefinisikannya pada saat run time. Ini menyebabkan sebagian besarconst
kerugian. Beberapa kelemahanconst
adalah:const
tidak dapat digunakan untuk mendefinisikan konstanta secara kondisional. Untuk mendefinisikan konstanta global, ia harus digunakan dalam lingkup terluar:Mengapa Anda tetap ingin melakukan itu? Satu aplikasi umum adalah untuk memeriksa apakah konstanta sudah ditentukan:
const
menerima skalar statis (nomor, string atau konstan lain sepertitrue
,false
,null
,__FILE__
), sedangkandefine()
mengambil ekspresi apapun. Karena PHP 5.6 ekspresi konstan juga diperbolehkanconst
:const
mengambil nama konstan polos, sedangkandefine()
menerima ekspresi apa pun sebagai nama. Ini memungkinkan untuk melakukan hal-hal seperti ini:const
s selalu peka huruf besar kecil, sedangkandefine()
memungkinkan Anda untuk mendefinisikan konstanta tidak peka huruf besar kecil dengan melewatkantrue
sebagai argumen ketiga (Catatan: mendefinisikan konstanta peka-huruf tidak berlaku lagi pada PHP 7.3.0.):Jadi, itulah sisi buruknya. Sekarang mari kita lihat alasan mengapa saya selalu menggunakan
const
kecuali jika salah satu dari situasi di atas terjadi:const
hanya membaca lebih baik. Ini adalah konstruksi bahasa alih-alih fungsi dan juga konsisten dengan cara Anda mendefinisikan konstanta di kelas.const
, sebagai konstruksi bahasa, dapat dianalisis secara statis dengan perkakas otomatis.const
mendefinisikan konstanta di namespace saat ini, sementaradefine()
harus melewati nama namespace lengkap:Karena
const
konstanta PHP 5.6 juga bisa berupa array, sementaradefine()
itu belum mendukung array. Namun, array akan didukung untuk kedua kasus di PHP 7.Akhirnya, perhatikan bahwa
const
juga dapat digunakan dalam kelas atau antarmuka untuk menentukan konstanta kelas atau antarmuka konstan.define
tidak dapat digunakan untuk tujuan ini:Ringkasan
Kecuali jika Anda memerlukan jenis definisi kondisional atau ekspresi, gunakan
const
s alih-alihdefine()
s - hanya demi keterbacaan!sumber
const
konstruksi bahasa - lihat wiki.php.net/rfc/const_scalar_exprsconst
adalah kurangnya tanda kutip, artinya diformat sama dengan yang digunakan dalam IDE Anda.define('a', $_GET['param']);
,const b = a;
bekerja dengan sempurna dan mendapatkan nilai saatconst c = $_GET['param'];
tidak valid Apakahconst
waktu kompilasi benar-benar? Saya kira tidak begitu ... (diuji pada PHP 7.0.7)Hingga PHP 5.3,
const
tidak bisa digunakan dalam lingkup global. Anda hanya bisa menggunakan ini dari dalam kelas. Ini harus digunakan ketika Anda ingin mengatur semacam opsi atau pengaturan konstan yang berkaitan dengan kelas itu. Atau mungkin Anda ingin membuat semacam enum.define
dapat digunakan untuk tujuan yang sama, tetapi hanya dapat digunakan dalam lingkup global. Seharusnya hanya digunakan untuk pengaturan global yang mempengaruhi seluruh aplikasi.Contoh
const
penggunaan yang baik adalah untuk menghilangkan angka ajaib. Lihatlah konstanta PDO . Ketika Anda perlu menentukan jenis pengambilan, Anda akan mengetikPDO::FETCH_ASSOC
, misalnya. Jika const tidak digunakan, Anda akan mengetik sesuatu seperti35
(atau apa punFETCH_ASSOC
yang didefinisikan sebagai). Ini tidak masuk akal bagi pembaca.Contoh
define
penggunaan yang baik mungkin menentukan jalur akar aplikasi Anda atau nomor versi pustaka.sumber
const
dengan ruang nama.Saya tahu ini sudah dijawab, tetapi tidak ada jawaban saat ini yang menyebutkan namespacing dan bagaimana pengaruhnya terhadap konstanta dan definisi.
Pada PHP 5.3, konstanta dan definisi hampir sama dalam banyak hal. Namun, masih ada beberapa perbedaan penting:
const FOO = 4 * 3;
tidak bekerja, tetapidefine('CONST', 4 * 3);
tidak.define
harus menyertakan namespace yang akan didefinisikan dalam namespace itu.Kode di bawah ini harus menggambarkan perbedaan.
Konten dari sub-array pengguna akan
['foo\\BAR' => 1, 'BAZ' => 2, 'foo\\BAZ' => 3]
.=== UPDATE ===
PHP 5.6 mendatang akan memungkinkan fleksibilitas yang lebih tinggi dengan
const
. Anda sekarang dapat mendefinisikan const dalam hal ekspresi, asalkan ekspresi tersebut terdiri dari const lain atau literal. Ini berarti yang berikut ini harus valid pada 5.6:Anda masih tidak akan dapat mendefinisikan const dalam hal variabel atau fungsi kembali, jadi
masih akan keluar.
sumber
FORTY_TWO
sebagai 54?Saya percaya bahwa pada PHP 5.3, Anda dapat menggunakan di
const
luar kelas, seperti yang ditunjukkan di sini dalam contoh kedua:http://www.php.net/manual/en/language.constants.syntax.php
sumber
define
Saya gunakan untuk konstanta global.const
Saya gunakan untuk konstanta kelas.Anda tidak bisa
define
masuk ke dalam ruang lingkup kelas, dan denganconst
Anda bisa. Tidak perlu dikatakan, Anda tidak dapat menggunakanconst
ruang lingkup kelas luar.Juga, dengan
const
, itu benar-benar menjadi anggota kelas, dan dengandefine
, itu akan didorong ke ruang lingkup global.sumber
Jawaban NikiC adalah yang terbaik, tetapi izinkan saya menambahkan peringatan yang tidak jelas ketika menggunakan ruang nama sehingga Anda tidak terjebak dengan perilaku yang tidak terduga. Yang perlu diingat adalah bahwa definisi selalu di namespace global kecuali jika Anda secara eksplisit menambahkan namespace sebagai bagian dari pengidentifikasi define. Apa yang tidak jelas tentang itu adalah bahwa pengidentifikasi namespaced mengalahkan pengidentifikasi global. Jadi:
menghasilkan:
Yang bagi saya membuat seluruh gagasan const tidak perlu membingungkan karena ide tentang const dalam lusinan bahasa lain adalah bahwa itu selalu sama di mana pun Anda berada dalam kode Anda, dan PHP tidak benar-benar menjamin itu.
sumber
BAR
dan\foo\BAR
hanya tidak konstanta yang sama. Saya setuju itu benar-benar membingungkan, tetapi jika Anda juga menganggap hal-hal seperti logika namespacing konsisten dengan cara ini, dan tidakconst
jugadefine()
tidak seperti makro C (#define
), maka PHP dapat memiliki beberapa alasan.Sebagian besar jawaban ini salah atau hanya menceritakan setengah dari cerita.
Sebagai contoh:
Contoh buruk:
Untuk membuat konstanta variabel, gunakan define () seperti:
sumber
Ya, const didefinisikan pada waktu kompilasi dan karena status nikic tidak dapat diberikan ekspresi, seperti yang dapat didefinisikan () dapat. Tetapi juga const tidak dapat dinyatakan secara kondisional (untuk alasan yang sama). yaitu. Anda tidak dapat melakukan ini:
Sedangkan Anda bisa dengan define (). Jadi, itu tidak benar-benar turun ke preferensi pribadi, ada cara yang benar dan salah untuk menggunakan keduanya.
Sebagai tambahan ... Saya ingin melihat semacam konst kelas yang dapat diberi ekspresi, semacam define () yang dapat diisolasi ke kelas?
sumber
Untuk menambahkan jawaban NikiC.
const
dapat digunakan di dalam kelas dengan cara berikut:Anda tidak dapat melakukan ini dengan
define()
.sumber
Tidak ada yang mengatakan apa-apa tentang php-doc, tetapi bagi saya itu juga argumen yang sangat signifikan untuk preferensi
const
:sumber
Dengan menetapkan kata kunci konstan, Anda akan mendapatkan fasilitas case-insensitive tetapi dengan const kata kunci yang Anda tidak.
sumber