php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
dba.c
Go to the documentation of this file.
1/*
2 +----------------------------------------------------------------------+
3 | Copyright (c) The PHP Group |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.01 of the PHP license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | https://www.php.net/license/3_01.txt |
9 | If you did not receive a copy of the PHP license and are unable to |
10 | obtain it through the world-wide-web, please send a note to |
11 | license@php.net so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Authors: Sascha Schumann <sascha@schumann.cx> |
14 | Marcus Boerger <helly@php.net> |
15 +----------------------------------------------------------------------+
16 */
17
18#ifdef HAVE_CONFIG_H
19#include <config.h>
20#endif
21
22#include "php.h"
23
24#ifdef HAVE_DBA
25
26#include "php_ini.h"
27#include <stdio.h>
28#include <fcntl.h>
29#ifdef HAVE_SYS_FILE_H
30#include <sys/file.h>
31#endif
32
33#include "php_dba.h"
34#include "ext/standard/info.h"
35#include "ext/standard/flock_compat.h" /* Compatibility for Windows */
36
37#include "php_gdbm.h"
38#include "php_ndbm.h"
39#include "php_dbm.h"
40#include "php_cdb.h"
41#include "php_db1.h"
42#include "php_db2.h"
43#include "php_db3.h"
44#include "php_db4.h"
45#include "php_flatfile.h"
46#include "php_inifile.h"
47#include "php_qdbm.h"
48#include "php_tcadb.h"
49#include "php_lmdb.h"
50#include "dba_arginfo.h"
51
55
57 const char *default_handler;
58 const dba_handler *default_hptr;
59 HashTable connections;
60 unsigned int connection_counter;
62
64
65#define DBA_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(dba, v)
66
67static PHP_GINIT_FUNCTION(dba);
68static PHP_GSHUTDOWN_FUNCTION(dba);
69
70zend_module_entry dba_module_entry = {
72 "dba",
73 ext_functions,
74 PHP_MINIT(dba),
75 PHP_MSHUTDOWN(dba),
76 NULL,
77 NULL,
78 PHP_MINFO(dba),
81 PHP_GINIT(dba),
82 PHP_GSHUTDOWN(dba),
83 NULL,
85};
86
87#ifdef COMPILE_DL_DBA
88#ifdef ZTS
90#endif
92#endif
93
94/* {{{ php_dba_make_key */
95static zend_string* php_dba_make_key(HashTable *key)
96{
97 zval *group, *name;
98 zend_string *group_str, *name_str;
100
101 if (zend_hash_num_elements(key) != 2) {
102 zend_argument_error(NULL, 1, "must have exactly two elements: \"key\" and \"name\"");
103 return NULL;
104 }
105
106 // TODO: Use ZEND_HASH_FOREACH_VAL() API?
109 group_str = zval_try_get_string(group);
110 if (!group_str) {
111 return NULL;
112 }
113
116 name_str = zval_try_get_string(name);
117 if (!name_str) {
118 zend_string_release_ex(group_str, false);
119 return NULL;
120 }
121
122 // TODO: Check ZSTR_LEN(name) != 0
123 if (ZSTR_LEN(group_str) == 0) {
124 zend_string_release_ex(group_str, false);
125 return name_str;
126 }
127
128 zend_string *key_str = zend_strpprintf(0, "[%s]%s", ZSTR_VAL(group_str), ZSTR_VAL(name_str));
129 zend_string_release_ex(group_str, false);
130 zend_string_release_ex(name_str, false);
131 return key_str;
132}
133/* }}} */
134
135#define DBA_RELEASE_HT_KEY_CREATION() if (key_ht) {zend_string_release_ex(key_str, false);}
136
137#define CHECK_DBA_CONNECTION(info) \
138 if (info == NULL) { \
139 zend_throw_error(NULL, "DBA connection has already been closed"); \
140 RETURN_THROWS(); \
141 }
142
143/* check whether the user has write access */
144#define DBA_WRITE_CHECK(info) \
145 if ((info)->mode != DBA_WRITER && (info)->mode != DBA_TRUNC && (info)->mode != DBA_CREAT) { \
146 php_error_docref(NULL, E_WARNING, "Cannot perform a modification on a readonly database"); \
147 RETURN_FALSE; \
148 }
149
150/* a DBA handler must have specific routines */
151
152#define DBA_NAMED_HND(alias, name, flags) \
153{\
154 #alias, flags, dba_open_##name, dba_close_##name, dba_fetch_##name, dba_update_##name, \
155 dba_exists_##name, dba_delete_##name, dba_firstkey_##name, dba_nextkey_##name, \
156 dba_optimize_##name, dba_sync_##name, dba_info_##name \
157},
158
159#define DBA_HND(name, flags) DBA_NAMED_HND(name, name, flags)
160
161/* }}} */
162
163/* {{{ globals */
164
165static const dba_handler handler[] = {
166#ifdef DBA_GDBM
167 DBA_HND(gdbm, DBA_LOCK_EXT) /* Locking done in library if set */
168#endif
169#ifdef DBA_DBM
170 DBA_HND(dbm, DBA_LOCK_ALL) /* No lock in lib */
171#endif
172#ifdef DBA_NDBM
173 DBA_HND(ndbm, DBA_LOCK_ALL) /* Could be done in library: filemode = 0644 + S_ENFMT */
174#endif
175#ifdef DBA_CDB
176 DBA_HND(cdb, DBA_STREAM_OPEN|DBA_LOCK_ALL) /* No lock in lib */
177#endif
178#ifdef DBA_CDB_BUILTIN
179 DBA_NAMED_HND(cdb_make, cdb, DBA_STREAM_OPEN|DBA_LOCK_ALL) /* No lock in lib */
180#endif
181#ifdef DBA_DB1
182 DBA_HND(db1, DBA_LOCK_ALL) /* No lock in lib */
183#endif
184#ifdef DBA_DB2
185 DBA_HND(db2, DBA_LOCK_ALL) /* No lock in lib */
186#endif
187#ifdef DBA_DB3
188 DBA_HND(db3, DBA_LOCK_ALL) /* No lock in lib */
189#endif
190#ifdef DBA_DB4
191 DBA_HND(db4, DBA_LOCK_ALL) /* No lock in lib */
192#endif
193#ifdef DBA_INIFILE
194 DBA_HND(inifile, DBA_STREAM_OPEN|DBA_LOCK_ALL|DBA_CAST_AS_FD) /* No lock in lib */
195#endif
196#ifdef DBA_FLATFILE
197 DBA_HND(flatfile, DBA_STREAM_OPEN|DBA_LOCK_ALL|DBA_NO_APPEND) /* No lock in lib */
198#endif
199#ifdef DBA_QDBM
200 DBA_HND(qdbm, DBA_LOCK_EXT)
201#endif
202#ifdef DBA_TCADB
203 DBA_HND(tcadb, DBA_LOCK_ALL)
204#endif
205#ifdef DBA_LMDB
206 DBA_HND(lmdb, DBA_LOCK_EXT)
207#endif
208 { NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
209};
210
211#ifdef DBA_FLATFILE
212#define DBA_DEFAULT "flatfile"
213#elif defined(DBA_DB4)
214#define DBA_DEFAULT "db4"
215#elif defined(DBA_DB3)
216#define DBA_DEFAULT "db3"
217#elif defined(DBA_DB2)
218#define DBA_DEFAULT "db2"
219#elif defined(DBA_DB1)
220#define DBA_DEFAULT "db1"
221#elif defined(DBA_GDBM)
222#define DBA_DEFAULT "gdbm"
223#elif defined(DBA_NBBM)
224#define DBA_DEFAULT "ndbm"
225#elif defined(DBA_DBM)
226#define DBA_DEFAULT "dbm"
227#elif defined(DBA_QDBM)
228#define DBA_DEFAULT "qdbm"
229#elif defined(DBA_TCADB)
230#define DBA_DEFAULT "tcadb"
231#elif defined(DBA_LMDB)
232#define DBA_DEFAULT "lmdb"
233#else
234#define DBA_DEFAULT ""
235#endif
236/* cdb/cdb_make and ini are no option here */
237
238static int le_pdb;
239
240static zend_class_entry *dba_connection_ce;
241static zend_object_handlers dba_connection_object_handlers;
242
243static void dba_close_info(dba_info *info)
244{
245 ZEND_ASSERT(info != NULL && "connection has already been closed");
246
247 if (info->hnd) {
248 info->hnd->close(info);
249 info->hnd = NULL;
250 }
251 ZEND_ASSERT(info->path);
252 zend_string_release_ex(info->path, info->flags&DBA_PERSISTENT);
253 info->path = NULL;
254
255 if (info->fp && info->fp != info->lock.fp) {
256 if (info->flags & DBA_PERSISTENT) {
257 php_stream_pclose(info->fp);
258 } else {
259 php_stream_close(info->fp);
260 }
261 }
262 if (info->lock.fp) {
263 if (info->flags & DBA_PERSISTENT) {
264 php_stream_pclose(info->lock.fp);
265 } else {
266 php_stream_close(info->lock.fp);
267 }
268 }
269
270 pefree(info, info->flags & DBA_PERSISTENT);
271 info = NULL;
272}
273
274static int remove_pconnection_from_list(zval *zv, void *p)
275{
276 zend_resource *le = Z_RES_P(zv);
277
278 if (le->ptr == p) {
280 }
281
283}
284
285static void close_pconnection(zend_resource *rsrc)
286{
287 dba_info *info = (dba_info *) rsrc->ptr;
288
289 dba_close_info(info);
290
291 rsrc->ptr = NULL;
292}
293
294static void dba_close_connection(dba_connection *connection)
295{
296 bool persistent = connection->info->flags & DBA_PERSISTENT;
297
298 if (!persistent) {
299 dba_close_info(connection->info);
300 }
301
302 connection->info = NULL;
303
304 if (connection->hash) {
305 zend_hash_del(&DBA_G(connections), connection->hash);
306 zend_string_release_ex(connection->hash, persistent);
307 connection->hash = NULL;
308 }
309}
310
311static zend_object *dba_connection_create_object(zend_class_entry *class_type)
312{
313 dba_connection *intern = zend_object_alloc(sizeof(dba_connection), class_type);
314
315 zend_object_std_init(&intern->std, class_type);
316 object_properties_init(&intern->std, class_type);
317
318 return &intern->std;
319}
320
321static zend_function *dba_connection_get_constructor(zend_object *object)
322{
323 zend_throw_error(NULL, "Cannot directly construct Dba\\Connection, use dba_open() or dba_popen() instead");
324 return NULL;
325}
326
327static zend_result dba_connection_cast_object(zend_object *obj, zval *result, int type)
328{
329 if (type == IS_LONG) {
330 /* For better backward compatibility, make (int) $dba return the object ID,
331 * similar to how it previously returned the resource ID. */
332 ZVAL_LONG(result, obj->handle);
333
334 return SUCCESS;
335 }
336
338}
339
340static inline dba_connection *dba_connection_from_obj(zend_object *obj)
341{
342 return (dba_connection *)((char *)(obj) - XtOffsetOf(dba_connection, std));
343}
344
345#define Z_DBA_CONNECTION_P(zv) dba_connection_from_obj(Z_OBJ_P(zv))
346#define Z_DBA_INFO_P(zv) Z_DBA_CONNECTION_P(zv)->info
347
348static void dba_connection_free_obj(zend_object *obj)
349{
350 dba_connection *connection = dba_connection_from_obj(obj);
351
352 if (connection->info) {
353 dba_close_connection(connection);
354 }
355
356 zend_object_std_dtor(&connection->std);
357}
358
359/* {{{ PHP_INI */
360static ZEND_INI_MH(OnUpdateDefaultHandler)
361{
362 const dba_handler *hptr;
363
364 if (!ZSTR_LEN(new_value)) {
365 DBA_G(default_hptr) = NULL;
366 return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
367 }
368
369 for (hptr = handler; hptr->name && strcasecmp(hptr->name, ZSTR_VAL(new_value)); hptr++);
370
371 if (!hptr->name) {
372 php_error_docref(NULL, E_WARNING, "No such handler: %s", ZSTR_VAL(new_value));
373 return FAILURE;
374 }
375 DBA_G(default_hptr) = hptr;
376 return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
377}
378
380 STD_PHP_INI_ENTRY("dba.default_handler", DBA_DEFAULT, PHP_INI_ALL, OnUpdateDefaultHandler, default_handler, zend_dba_globals, dba_globals)
382/* }}} */
383
384/* {{{ PHP_GINIT_FUNCTION */
385static PHP_GINIT_FUNCTION(dba)
386{
387#if defined(COMPILE_DL_DBA) && defined(ZTS)
389#endif
390 dba_globals->default_handler = "";
391 dba_globals->default_hptr = NULL;
392 zend_hash_init(&dba_globals->connections, 0, NULL, NULL, true);
393 GC_MAKE_PERSISTENT_LOCAL(&dba_globals->connections);
394}
395/* }}} */
396
397static PHP_GSHUTDOWN_FUNCTION(dba)
398{
399 zend_hash_destroy(&dba_globals->connections);
400}
401
402/* {{{ PHP_MINIT_FUNCTION */
404{
406 le_pdb = zend_register_list_destructors_ex(NULL, close_pconnection, "dba persistent", module_number);
407 register_dba_symbols(module_number);
408
409 dba_connection_ce = register_class_Dba_Connection();
410 dba_connection_ce->create_object = dba_connection_create_object;
411 dba_connection_ce->default_object_handlers = &dba_connection_object_handlers;
412
413 memcpy(&dba_connection_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
414 dba_connection_object_handlers.offset = XtOffsetOf(dba_connection, std);
415 dba_connection_object_handlers.free_obj = dba_connection_free_obj;
416 dba_connection_object_handlers.get_constructor = dba_connection_get_constructor;
417 dba_connection_object_handlers.clone_obj = NULL;
418 dba_connection_object_handlers.cast_object = dba_connection_cast_object;
419 dba_connection_object_handlers.compare = zend_objects_not_comparable;
420
421 return SUCCESS;
422}
423/* }}} */
424
425/* {{{ PHP_MSHUTDOWN_FUNCTION */
427{
429 return SUCCESS;
430}
431/* }}} */
432
433#include "zend_smart_str.h"
434
435/* {{{ PHP_MINFO_FUNCTION */
437{
438 const dba_handler *hptr;
439 smart_str handlers = {0};
440
441 for(hptr = handler; hptr->name; hptr++) {
442 smart_str_appends(&handlers, hptr->name);
443 smart_str_appendc(&handlers, ' ');
444 }
445
447 php_info_print_table_row(2, "DBA support", "enabled");
448 if (handlers.s) {
449 smart_str_0(&handlers);
450 php_info_print_table_row(2, "Supported handlers", ZSTR_VAL(handlers.s));
451 smart_str_free(&handlers);
452 } else {
453 php_info_print_table_row(2, "Supported handlers", "none");
454 }
457}
458/* }}} */
459
460/* {{{ php_dba_update */
461static void php_dba_update(INTERNAL_FUNCTION_PARAMETERS, int mode)
462{
463 zval *id;
464 dba_info *info = NULL;
465 HashTable *key_ht = NULL;
466 zend_string *key_str = NULL;
468
470 Z_PARAM_ARRAY_HT_OR_STR(key_ht, key_str)
472 Z_PARAM_OBJECT_OF_CLASS(id, dba_connection_ce);
474
475 info = Z_DBA_INFO_P(id);
476 CHECK_DBA_CONNECTION(info);
477 DBA_WRITE_CHECK(info);
478
479 if (key_ht) {
480 key_str = php_dba_make_key(key_ht);
481 if (!key_str) {
482 // TODO ValueError?
484 }
485 }
486
487 RETVAL_BOOL(info->hnd->update(info, key_str, value, mode) == SUCCESS);
488 DBA_RELEASE_HT_KEY_CREATION();
489}
490/* }}} */
491
492/* {{{ php_find_dbm */
493static dba_info *php_dba_find(const zend_string *path)
494{
495 zval *zv;
496
497 ZEND_HASH_MAP_FOREACH_VAL(&DBA_G(connections), zv) {
498 dba_info *info = Z_DBA_INFO_P(zv);
499 if (info && zend_string_equals(path, info->path)) {
500 return info;
501 }
503
504 return NULL;
505}
506/* }}} */
507
508static zend_always_inline zend_string *php_dba_zend_string_dup_safe(zend_string *s, bool persistent)
509{
510 if (ZSTR_IS_INTERNED(s) && !persistent) {
511 return s;
512 } else {
513 zend_string *duplicated_str = zend_string_init(ZSTR_VAL(s), ZSTR_LEN(s), persistent);
514 if (persistent) {
515 GC_MAKE_PERSISTENT_LOCAL(duplicated_str);
516 }
517 return duplicated_str;
518 }
519}
520
521/* {{{ php_dba_open */
522static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, bool persistent)
523{
524 dba_mode_t modenr;
525 const dba_handler *hptr;
526 const char *error = NULL;
527 int lock_mode, lock_flag = 0;
528 const char *file_mode;
529 const char *lock_file_mode = NULL;
530 int persistent_flag = persistent ? STREAM_OPEN_PERSISTENT : 0;
531 char *lock_name;
532#ifdef PHP_WIN32
533 bool restarted = 0;
534 bool need_creation = 0;
535#endif
536
537 zend_string *path;
539 zend_string *handler_str = NULL;
540 zend_long permission = 0644;
541 zend_long map_size = 0;
542 zend_long driver_flags = DBA_DEFAULT_DRIVER_FLAGS;
543 bool is_flags_null = true;
544
545 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "PS|S!lll!", &path, &mode, &handler_str,
546 &permission, &map_size, &driver_flags, &is_flags_null)) {
548 }
549
550 if (ZSTR_LEN(path) == 0) {
553 }
554 if (ZSTR_LEN(mode) == 0) {
557 }
558 if (handler_str && ZSTR_LEN(handler_str) == 0) {
561 }
562 // TODO Check Value for permission
563 if (map_size < 0) {
564 zend_argument_value_error(5, "must be greater than or equal to 0");
566 }
567
568 if (!is_flags_null && driver_flags < 0) {
569 zend_argument_value_error(6, "must be greater than or equal to 0");
571 }
572
573 char *resource_key;
574 size_t resource_key_len = spprintf(&resource_key, 0,
575 "dba_%d_%u_%s_%s_%s", persistent, persistent ? 0 : DBA_G(connection_counter)++, ZSTR_VAL(path), ZSTR_VAL(mode), handler_str ? ZSTR_VAL(handler_str) : ""
576 );
577
578 if (persistent) {
579 zend_resource *le;
580
581 /* try to find if we already have this link in our persistent list */
582 if ((le = zend_hash_str_find_ptr(&EG(persistent_list), resource_key, resource_key_len)) != NULL) {
583 if (le->type != le_pdb) {
584 // TODO This should never happen
585 efree(resource_key);
587 }
588
589 object_init_ex(return_value, dba_connection_ce);
590 dba_connection *connection = Z_DBA_CONNECTION_P(return_value);
591 connection->info = (dba_info *)le->ptr;
592 connection->hash = zend_string_init(resource_key, resource_key_len, persistent);
593 if (persistent) {
594 GC_MAKE_PERSISTENT_LOCAL(connection->hash);
595 }
596
597 if (zend_hash_exists(&DBA_G(connections), connection->hash)) {
598 zend_hash_del(&DBA_G(connections), connection->hash);
599 }
600
601 zend_hash_add_new(&DBA_G(connections), connection->hash, return_value);
602 efree(resource_key);
603 return;
604 }
605 }
606
607 if (!handler_str) {
608 hptr = DBA_G(default_hptr);
609 if (!hptr) {
610 php_error_docref(NULL, E_WARNING, "No default handler selected");
611 efree(resource_key);
613 }
614 ZEND_ASSERT(hptr->name);
615 } else {
616 /* Loop through global static var handlers to see if such a handler exists */
617 for (hptr = handler; hptr->name && strcasecmp(hptr->name, ZSTR_VAL(handler_str)); hptr++);
618
619 if (!hptr->name) {
620 php_error_docref(NULL, E_WARNING, "Handler \"%s\" is not available", ZSTR_VAL(handler_str));
621 efree(resource_key);
623 }
624 }
625
626 /* Check mode: [rwnc][dl-]?t?
627 * r: Read
628 * w: Write
629 * n: Create/Truncate
630 * c: Create
631 *
632 * d: force lock on database file
633 * l: force lock on lck file
634 * -: ignore locking
635 *
636 * t: test open database, warning if locked
637 */
638 bool is_test_lock = false;
639 bool is_db_lock = false;
640 bool is_lock_ignored = false;
641 // bool is_file_lock = false;
642
643 if (ZSTR_LEN(mode) > 3) {
644 zend_argument_value_error(2, "must be at most 3 characters");
645 efree(resource_key);
647 }
648 if (ZSTR_LEN(mode) == 3) {
649 if (ZSTR_VAL(mode)[2] != 't') {
650 zend_argument_value_error(2, "third character must be \"t\"");
651 efree(resource_key);
653 }
654 is_test_lock = true;
655 }
656 if (ZSTR_LEN(mode) >= 2) {
657 switch (ZSTR_VAL(mode)[1]) {
658 case 't':
659 is_test_lock = true;
660 break;
661 case '-':
662 if ((hptr->flags & DBA_LOCK_ALL) == 0) {
663 php_error_docref(NULL, E_WARNING, "Locking cannot be disabled for handler %s", hptr->name);
664 efree(resource_key);
666 }
667 is_lock_ignored = true;
668 lock_flag = 0;
669 break;
670 case 'd':
671 is_db_lock = true;
672 if ((hptr->flags & DBA_LOCK_ALL) == 0) {
673 lock_flag = (hptr->flags & DBA_LOCK_ALL);
674 break;
675 }
677 case 'l':
678 // is_file_lock = true;
679 lock_flag = DBA_LOCK_ALL;
680 if ((hptr->flags & DBA_LOCK_ALL) == 0) {
681 php_error_docref(NULL, E_NOTICE, "Handler %s does locking internally", hptr->name);
682 }
683 break;
684 default:
685 zend_argument_value_error(2, "second character must be one of \"d\", \"l\", \"-\", or \"t\"");
686 efree(resource_key);
688 }
689 } else {
690 lock_flag = (hptr->flags&DBA_LOCK_ALL);
691 is_db_lock = true;
692 }
693
694 switch (ZSTR_VAL(mode)[0]) {
695 case 'r':
696 modenr = DBA_READER;
697 lock_mode = (lock_flag & DBA_LOCK_READER) ? LOCK_SH : 0;
698 file_mode = "r";
699 break;
700 case 'w':
701 modenr = DBA_WRITER;
702 lock_mode = (lock_flag & DBA_LOCK_WRITER) ? LOCK_EX : 0;
703 file_mode = "r+b";
704 break;
705 case 'c': {
706#ifdef PHP_WIN32
707 if (hptr->flags & (DBA_NO_APPEND|DBA_CAST_AS_FD)) {
709 need_creation = (SUCCESS != php_stream_stat_path(ZSTR_VAL(path), &ssb));
710 }
711#endif
712 modenr = DBA_CREAT;
713 lock_mode = (lock_flag & DBA_LOCK_CREAT) ? LOCK_EX : 0;
714 if (lock_mode) {
715 if (is_db_lock) {
716 /* the create/append check will be done on the lock
717 * when the lib opens the file it is already created
718 */
719 file_mode = "r+b"; /* read & write, seek 0 */
720#ifdef PHP_WIN32
721 if (!need_creation) {
722 lock_file_mode = "r+b";
723 } else
724#endif
725 lock_file_mode = "a+b"; /* append */
726 } else {
727#ifdef PHP_WIN32
728 if (!need_creation) {
729 file_mode = "r+b";
730 } else
731#endif
732 file_mode = "a+b"; /* append */
733 lock_file_mode = "w+b"; /* create/truncate */
734 }
735 } else {
736#ifdef PHP_WIN32
737 if (!need_creation) {
738 file_mode = "r+b";
739 } else
740#endif
741 file_mode = "a+b";
742 }
743 /* In case of the 'a+b' append mode, the handler is responsible
744 * to handle any rewind problems (see flatfile handler).
745 */
746 break;
747 }
748 case 'n':
749 modenr = DBA_TRUNC;
750 lock_mode = (lock_flag & DBA_LOCK_TRUNC) ? LOCK_EX : 0;
751 file_mode = "w+b";
752 break;
753 default:
754 zend_argument_value_error(2, "first character must be one of \"r\", \"w\", \"c\", or \"n\"");
755 efree(resource_key);
757 }
758 if (!lock_file_mode) {
759 lock_file_mode = file_mode;
760 }
761 if (is_test_lock) {
762 if (is_lock_ignored) {
763 zend_argument_value_error(2, "cannot combine mode \"-\" (no lock) and \"t\" (test lock)");
764 efree(resource_key);
766 }
767 if (!lock_mode) {
768 if ((hptr->flags & DBA_LOCK_ALL) == 0) {
769 php_error_docref(NULL, E_WARNING, "Handler %s uses its own locking which doesn't support mode modifier t (test lock)", hptr->name);
770 efree(resource_key);
772 } else {
773 php_error_docref(NULL, E_WARNING, "Handler %s doesn't uses locking for this mode which makes modifier t (test lock) obsolete", hptr->name);
774 efree(resource_key);
776 }
777 } else {
778 lock_mode |= LOCK_NB; /* test =: non blocking */
779 }
780 }
781
782 zval *connection_zval;
783 dba_connection *connection;
784 if ((connection_zval = zend_hash_str_find(&DBA_G(connections), resource_key, resource_key_len)) == NULL) {
785 object_init_ex(return_value, dba_connection_ce);
786 connection = Z_DBA_CONNECTION_P(return_value);
787
788 connection->info = pecalloc(1, sizeof(dba_info), persistent);
789 connection->info->path = php_dba_zend_string_dup_safe(path, persistent);
790 connection->info->mode = modenr;
791 connection->info->file_permission = permission;
792 connection->info->map_size = map_size;
793 connection->info->driver_flags = driver_flags;
794 connection->info->flags = (hptr->flags & ~DBA_LOCK_ALL) | (lock_flag & DBA_LOCK_ALL) | (persistent ? DBA_PERSISTENT : 0);
795 connection->info->lock.mode = lock_mode;
796 connection->hash = zend_string_init(resource_key, resource_key_len, persistent);
797 if (persistent) {
798 GC_MAKE_PERSISTENT_LOCAL(connection->hash);
799 }
800 } else {
801 ZVAL_COPY(return_value, connection_zval);
802 connection = Z_DBA_CONNECTION_P(return_value);
803 }
804
805 /* if any open call is a locking call:
806 * check if we already have a locking call open that should block this call
807 * the problem is some systems would allow read during write
808 */
809 if (hptr->flags & DBA_LOCK_ALL) {
810 dba_info *other;
811 if ((other = php_dba_find(connection->info->path)) != NULL) {
812 if ( ( (lock_mode&LOCK_EX) && (other->lock.mode&(LOCK_EX|LOCK_SH)) )
813 || ( (other->lock.mode&LOCK_EX) && (lock_mode&(LOCK_EX|LOCK_SH)) )
814 ) {
815 error = "Unable to establish lock (database file already open)"; /* force failure exit */
816 }
817 }
818 }
819
820#ifdef PHP_WIN32
821restart:
822#endif
823 if (!error && lock_mode) {
824 if (is_db_lock) {
825 lock_name = ZSTR_VAL(path);
826 } else {
827 spprintf(&lock_name, 0, "%s.lck", ZSTR_VAL(connection->info->path));
828 if (!strcmp(file_mode, "r")) {
829 zend_string *opened_path = NULL;
830 /* when in read only mode try to use existing .lck file first */
831 /* do not log errors for .lck file while in read only mode on .lck file */
832 lock_file_mode = "rb";
833 connection->info->lock.fp = php_stream_open_wrapper(lock_name, lock_file_mode, STREAM_MUST_SEEK|IGNORE_PATH|persistent_flag, &opened_path);
834 if (opened_path) {
835 zend_string_release_ex(opened_path, 0);
836 }
837 }
838 if (!connection->info->lock.fp) {
839 /* when not in read mode or failed to open .lck file read only. now try again in create(write) mode and log errors */
840 lock_file_mode = "a+b";
841 }
842 }
843 if (!connection->info->lock.fp) {
844 zend_string *opened_path = NULL;
845 connection->info->lock.fp = php_stream_open_wrapper(lock_name, lock_file_mode, STREAM_MUST_SEEK|REPORT_ERRORS|IGNORE_PATH|persistent_flag, &opened_path);
846 if (connection->info->lock.fp) {
847 if (is_db_lock) {
848 if (opened_path) {
849 /* replace the path info with the real path of the opened file */
850 zend_string_release_ex(connection->info->path, persistent);
851 connection->info->path = php_dba_zend_string_dup_safe(opened_path, persistent);
852 } else {
853 error = "Unable to determine path for locking";
854 }
855 }
856 }
857 if (opened_path) {
858 zend_string_release_ex(opened_path, 0);
859 opened_path = NULL;
860 }
861 }
862 if (!is_db_lock) {
863 efree(lock_name);
864 }
865 if (!connection->info->lock.fp) {
866 /* stream operation already wrote an error message */
867 goto fail;
868 }
869 if (!error && !php_stream_supports_lock(connection->info->lock.fp)) {
870 error = "Stream does not support locking";
871 }
872 if (!error && php_stream_lock(connection->info->lock.fp, lock_mode)) {
873 error = "Unable to establish lock"; /* force failure exit */
874 }
875 }
876
877 /* centralised open stream for builtin */
878 if (!error && (hptr->flags&DBA_STREAM_OPEN)==DBA_STREAM_OPEN) {
879 if (connection->info->lock.fp && is_db_lock) {
880 connection->info->fp = connection->info->lock.fp; /* use the same stream for locking and database access */
881 } else {
882 connection->info->fp = php_stream_open_wrapper(ZSTR_VAL(connection->info->path), file_mode, STREAM_MUST_SEEK|REPORT_ERRORS|IGNORE_PATH|persistent_flag, NULL);
883 }
884 if (!connection->info->fp) {
885 /* stream operation already wrote an error message */
886 goto fail;
887 }
888 if (hptr->flags & (DBA_NO_APPEND|DBA_CAST_AS_FD)) {
889 /* Needed because some systems do not allow to write to the original
890 * file contents with O_APPEND being set.
891 */
892 if (SUCCESS != php_stream_cast(connection->info->fp, PHP_STREAM_AS_FD, (void*)&connection->info->fd, 1)) {
893 php_error_docref(NULL, E_WARNING, "Could not cast stream");
894 goto fail;
895#ifdef F_SETFL
896 } else if (modenr == DBA_CREAT) {
897 int flags = fcntl(connection->info->fd, F_GETFL);
898 fcntl(connection->info->fd, F_SETFL, flags & ~O_APPEND);
899#elif defined(PHP_WIN32)
900 } else if (modenr == DBA_CREAT && need_creation && !restarted) {
901 if (connection->info->lock.fp != NULL) {
903 }
904 if (connection->info->fp != connection->info->lock.fp) {
906 }
907 connection->info->fp = NULL;
908 connection->info->lock.fp = NULL;
909 connection->info->fd = -1;
910
911 lock_file_mode = "r+b";
912
913 restarted = 1;
914 goto restart;
915#endif
916 }
917 }
918 }
919
920 if (error || hptr->open(connection->info, &error) == FAILURE) {
921 if (EXPECTED(!EG(exception))) {
922 if (error) {
923 php_error_docref(NULL, E_WARNING, "Driver initialization failed for handler: %s: %s", hptr->name, error);
924 } else {
925 php_error_docref(NULL, E_WARNING, "Driver initialization failed for handler: %s", hptr->name);
926 }
927 }
928 goto fail;
929 }
930
931 connection->info->hnd = hptr;
932
933 if (persistent) {
934 if (zend_register_persistent_resource(resource_key, resource_key_len, connection->info, le_pdb) == NULL) {
935 php_error_docref(NULL, E_WARNING, "Could not register persistent resource");
936 efree(resource_key);
937 dba_close_connection(connection);
940 }
941 }
942
943 zend_hash_add_new(&DBA_G(connections), connection->hash, return_value);
944 efree(resource_key);
945 return;
946fail:
947 efree(resource_key);
948 zend_string_release_ex(connection->hash, persistent);
949 dba_close_info(connection->info);
950 connection->info = NULL;
953}
954/* }}} */
955
956/* {{{ Opens path using the specified handler in mode persistently */
958{
959 php_dba_open(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
960}
961/* }}} */
962
963/* {{{ Opens path using the specified handler in mode*/
965{
966 php_dba_open(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
967}
968/* }}} */
969
970/* {{{ Closes database */
972{
973 zval *id;
974 dba_connection *connection = NULL;
975
976 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &id, dba_connection_ce) == FAILURE) {
978 }
979
980 connection = Z_DBA_CONNECTION_P(id);
981 CHECK_DBA_CONNECTION(connection->info);
982
983 bool persistent = connection->info->flags & DBA_PERSISTENT;
984
985 dba_close_connection(connection);
986
987 if (persistent) {
988 zend_hash_apply_with_argument(&EG(persistent_list), remove_pconnection_from_list, (void *) connection->info);
989 }
990}
991/* }}} */
992
993/* {{{ Checks, if the specified key exists */
995{
996 zval *id;
997 dba_info *info = NULL;
998 HashTable *key_ht = NULL;
999 zend_string *key_str = NULL;
1000
1002 Z_PARAM_ARRAY_HT_OR_STR(key_ht, key_str)
1003 Z_PARAM_OBJECT_OF_CLASS(id, dba_connection_ce);
1005
1006 info = Z_DBA_INFO_P(id);
1007 CHECK_DBA_CONNECTION(info);
1008
1009 if (key_ht) {
1010 key_str = php_dba_make_key(key_ht);
1011 if (!key_str) {
1012 // TODO ValueError?
1014 }
1015 }
1016
1017 RETVAL_BOOL(info->hnd->exists(info, key_str) == SUCCESS);
1018 DBA_RELEASE_HT_KEY_CREATION();
1019}
1020/* }}} */
1021
1022/* {{{ Fetches the data associated with key */
1024{
1025 zval *id;
1026 dba_info *info = NULL;
1027 HashTable *key_ht = NULL;
1028 zend_string *key_str = NULL;
1029 zend_long skip = 0;
1030
1031 /* Check for legacy signature */
1032 if (ZEND_NUM_ARGS() == 3) {
1034 Z_PARAM_ARRAY_HT_OR_STR(key_ht, key_str)
1035 Z_PARAM_LONG(skip)
1036 Z_PARAM_OBJECT_OF_CLASS(id, dba_connection_ce);
1037 ZEND_PARSE_PARAMETERS_END_EX(goto standard;);
1038
1039 zend_error(E_DEPRECATED, "Calling dba_fetch() with $dba at the 3rd parameter is deprecated");
1041 RETURN_THROWS();
1042 }
1043 } else {
1044 standard:
1046 Z_PARAM_ARRAY_HT_OR_STR(key_ht, key_str)
1047 Z_PARAM_OBJECT_OF_CLASS(id, dba_connection_ce);
1049 Z_PARAM_LONG(skip)
1051 }
1052
1053 info = Z_DBA_INFO_P(id);
1054 CHECK_DBA_CONNECTION(info);
1055
1056 if (key_ht) {
1057 key_str = php_dba_make_key(key_ht);
1058 if (!key_str) {
1059 // TODO ValueError?
1061 }
1062 }
1063
1064 if (skip != 0) {
1065 if (!strcmp(info->hnd->name, "cdb")) {
1066 // TODO ValueError?
1067 if (skip < 0) {
1068 php_error_docref(NULL, E_NOTICE, "Handler %s accepts only skip values greater than or equal to zero, using skip=0", info->hnd->name);
1069 skip = 0;
1070 }
1071 } else if (!strcmp(info->hnd->name, "inifile")) {
1072 /* "-1" is comparable to 0 but allows a non restrictive
1073 * access which is faster. For example 'inifile' uses this
1074 * to allow faster access when the key was already found
1075 * using firstkey/nextkey. However explicitly setting the
1076 * value to 0 ensures the first value.
1077 */
1078 if (skip < -1) {
1079 // TODO ValueError?
1080 php_error_docref(NULL, E_NOTICE, "Handler %s accepts only skip value -1 and greater, using skip=0", info->hnd->name);
1081 skip = 0;
1082 }
1083 } else {
1084 php_error_docref(NULL, E_NOTICE, "Handler %s does not support optional skip parameter, the value will be ignored", info->hnd->name);
1085 skip = 0;
1086 }
1087 }
1088
1090 if ((val = info->hnd->fetch(info, key_str, skip)) == NULL) {
1091 DBA_RELEASE_HT_KEY_CREATION();
1093 }
1094 DBA_RELEASE_HT_KEY_CREATION();
1095 RETURN_STR(val);
1096}
1097/* }}} */
1098
1099/* {{{ Splits an inifile key into an array of the form array(0=>group,1=>value_name) but returns false if input is false or null */
1101{
1102 zval *zkey;
1103 char *key, *name;
1104 size_t key_len;
1105
1107 if (Z_TYPE_P(zkey) == IS_NULL || (Z_TYPE_P(zkey) == IS_FALSE)) {
1108 php_error_docref(NULL, E_DEPRECATED, "Passing false or null is deprecated since 8.4");
1110 }
1111 }
1112 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &key, &key_len) == FAILURE) {
1113 RETURN_THROWS();
1114 }
1116 if (key[0] == '[' && (name = strchr(key, ']')) != NULL) {
1118 add_next_index_stringl(return_value, name+1, key_len - (name - key + 1));
1119 } else {
1122 }
1123}
1124/* }}} */
1125
1126/* {{{ Resets the internal key pointer and returns the first key */
1128{
1129 zval *id;
1130 dba_info *info = NULL;
1131
1132 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &id, dba_connection_ce) == FAILURE) {
1133 RETURN_THROWS();
1134 }
1135
1136 info = Z_DBA_INFO_P(id);
1137 CHECK_DBA_CONNECTION(info);
1138
1139 zend_string *fkey = info->hnd->firstkey(info);
1140
1141 if (fkey) {
1142 RETURN_STR(fkey);
1143 }
1144
1146}
1147/* }}} */
1148
1149/* {{{ Returns the next key */
1151{
1152 zval *id;
1153 dba_info *info = NULL;
1154
1155 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &id, dba_connection_ce) == FAILURE) {
1156 RETURN_THROWS();
1157 }
1158
1159 info = Z_DBA_INFO_P(id);
1160 CHECK_DBA_CONNECTION(info);
1161
1162 zend_string *nkey = info->hnd->nextkey(info);
1163
1164 if (nkey) {
1165 RETURN_STR(nkey);
1166 }
1167
1169}
1170/* }}} */
1171
1172/* {{{ Deletes the entry associated with key
1173 If inifile: remove all other key lines */
1175{
1176 zval *id;
1177 dba_info *info = NULL;
1178 HashTable *key_ht = NULL;
1179 zend_string *key_str = NULL;
1180
1182 Z_PARAM_ARRAY_HT_OR_STR(key_ht, key_str)
1183 Z_PARAM_OBJECT_OF_CLASS(id, dba_connection_ce);
1185
1186 info = Z_DBA_INFO_P(id);
1187 CHECK_DBA_CONNECTION(info);
1188 DBA_WRITE_CHECK(info);
1189
1190 if (key_ht) {
1191 key_str = php_dba_make_key(key_ht);
1192 if (!key_str) {
1193 // TODO ValueError?
1195 }
1196 }
1197
1198 RETVAL_BOOL(info->hnd->delete(info, key_str) == SUCCESS);
1199 DBA_RELEASE_HT_KEY_CREATION();
1200}
1201/* }}} */
1202
1203/* {{{ If not inifile: Insert value as key, return false, if key exists already
1204 If inifile: Add vakue as key (next instance of key) */
1206{
1207 php_dba_update(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
1208}
1209/* }}} */
1210
1211/* {{{ Inserts value as key, replaces key, if key exists already
1212 If inifile: remove all other key lines */
1214{
1215 php_dba_update(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
1216}
1217/* }}} */
1218
1219/* {{{ Optimizes (e.g. clean up, vacuum) database */
1221{
1222 zval *id;
1223 dba_info *info = NULL;
1224
1225 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &id, dba_connection_ce) == FAILURE) {
1226 RETURN_THROWS();
1227 }
1228
1229 info = Z_DBA_INFO_P(id);
1230 CHECK_DBA_CONNECTION(info);
1231 DBA_WRITE_CHECK(info);
1232
1233 if (info->hnd->optimize(info) == SUCCESS) {
1235 }
1236
1238}
1239/* }}} */
1240
1241/* {{{ Synchronizes database */
1243{
1244 zval *id;
1245 dba_info *info = NULL;
1246
1247 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &id, dba_connection_ce) == FAILURE) {
1248 RETURN_THROWS();
1249 }
1250
1251 info = Z_DBA_INFO_P(id);
1252 CHECK_DBA_CONNECTION(info);
1253
1254 if (info->hnd->sync(info) == SUCCESS) {
1256 }
1257
1259}
1260/* }}} */
1261
1262/* {{{ List configured database handlers */
1264{
1265 const dba_handler *hptr;
1266 bool full_info = 0;
1267
1268 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &full_info) == FAILURE) {
1269 RETURN_THROWS();
1270 }
1271
1273
1274 for(hptr = handler; hptr->name; hptr++) {
1275 if (full_info) {
1276 // TODO: avoid reallocation ???
1277 char *str = hptr->info(hptr, NULL);
1278 add_assoc_string(return_value, hptr->name, str);
1279 efree(str);
1280 } else {
1282 }
1283 }
1284}
1285/* }}} */
1286
1287/* {{{ List opened databases */
1289{
1291 RETURN_THROWS();
1292 }
1293
1295
1296 zval *zv;
1297 ZEND_HASH_MAP_FOREACH_VAL(&DBA_G(connections), zv) {
1298 dba_connection *connection = Z_DBA_CONNECTION_P(zv);
1299 if (connection->info) {
1300 add_index_str(return_value, connection->std.handle, zend_string_copy(connection->info->path));
1301 }
1303}
1304/* }}} */
1305
1306#endif /* HAVE_DBA */
bool exception
Definition assert.c:30
strchr(string $haystack, string $needle, bool $before_needle=false)
char s[4]
Definition cdf.c:77
dba_handlers(bool $full_info=false)
Definition dba.stub.php:61
dba_exists(string|array $key, Dba\Connection $dba)
Definition dba.stub.php:32
dba_list()
Definition dba.stub.php:64
dba_sync(Dba\Connection $dba)
Definition dba.stub.php:55
dba_close(Dba\Connection $dba)
Definition dba.stub.php:30
dba_delete(string|array $key, Dba\Connection $dba)
Definition dba.stub.php:47
dba_key_split(string|false|null $key)
Definition dba.stub.php:41
dba_nextkey(Dba\Connection $dba)
Definition dba.stub.php:45
dba_insert(string|array $key, string $value, Dba\Connection $dba)
Definition dba.stub.php:49
dba_optimize(Dba\Connection $dba)
Definition dba.stub.php:53
dba_popen(string $path, string $mode, ?string $handler=null, int $permission=0o644, int $map_size=0, ?int $flags=null)
Definition dba.stub.php:26
dba_open(string $path, string $mode, ?string $handler=null, int $permission=0o644, int $map_size=0, ?int $flags=null)
Definition dba.stub.php:28
dba_replace(string|array $key, string $value, Dba\Connection $dba)
Definition dba.stub.php:51
dba_fetch(string|array $key, $dba, $skip=0)
Definition dba.stub.php:38
dba_firstkey(Dba\Connection $dba)
Definition dba.stub.php:43
error($message)
Definition ext_skel.php:22
zend_ffi_type * type
Definition ffi.c:3812
zval * zv
Definition ffi.c:3975
memcpy(ptr1, ptr2, size)
zval * val
Definition ffi.c:4262
ffi persistent
Definition ffi.c:3633
#define LOCK_NB
char * mode
#define NULL
Definition gdcache.h:45
#define SUCCESS
Definition hash_sha3.c:261
foreach($dp as $el) foreach( $dp as $el) if( $pass2< 2) echo ""
PHPAPI ZEND_COLD void php_error_docref(const char *docref, int type, const char *format,...)
Definition main.c:1173
php_info_print_table_start()
Definition info.c:1064
php_info_print_table_row(2, "PDO Driver for Firebird", "enabled")
php_info_print_table_end()
Definition info.c:1074
#define PHP_GINIT
Definition php.h:397
#define PHP_FUNCTION
Definition php.h:364
#define PHP_MSHUTDOWN_FUNCTION
Definition php.h:401
#define PHP_MINFO
Definition php.h:396
#define PHP_MINIT_FUNCTION
Definition php.h:400
#define PHP_MSHUTDOWN
Definition php.h:393
#define PHP_MINFO_FUNCTION
Definition php.h:404
#define PHP_GINIT_FUNCTION
Definition php.h:405
#define PHP_GSHUTDOWN_FUNCTION
Definition php.h:406
#define PHP_MINIT
Definition php.h:392
#define PHP_MODULE_GLOBALS
Definition php.h:408
#define PHP_GSHUTDOWN
Definition php.h:398
#define PHP_DBA_VERSION
Definition php_dba.h:21
unsigned const char * pos
Definition php_ffi.h:52
#define PHP_INI_ALL
Definition php_ini.h:45
#define PHP_INI_BEGIN
Definition php_ini.h:52
#define STD_PHP_INI_ENTRY
Definition php_ini.h:64
#define PHP_INI_END
Definition php_ini.h:53
zend_stack handlers
Definition php_output.h:139
unsigned char key[REFLECTION_KEY_LEN]
#define php_stream_cast(stream, as, ret, show_err)
#define php_stream_stat_path(path, ssb)
#define php_stream_pclose(stream)
#define REPORT_ERRORS
#define IGNORE_PATH
#define PHP_STREAM_FREE_CLOSE_PERSISTENT
#define php_stream_supports_lock(stream)
#define php_stream_free(stream, close_options)
#define php_stream_close(stream)
#define PHP_STREAM_FREE_CLOSE
#define STREAM_OPEN_PERSISTENT
#define php_stream_lock(stream, mode)
#define php_stream_open_wrapper(path, mode, options, opened)
#define PHP_STREAM_AS_FD
#define STREAM_MUST_SEEK
struct _php_stream_statbuf php_stream_statbuf
bool fail
Definition session.c:1065
p
Definition session.c:1105
#define spprintf
Definition spprintf.h:29
zend_object *(* create_object)(zend_class_entry *class_type)
Definition zend.h:195
const zend_object_handlers * default_object_handlers
Definition zend.h:186
zend_object_compare_t compare
zend_object_free_obj_t free_obj
zend_object_cast_t cast_object
zend_object_get_constructor_t get_constructor
zend_object_clone_obj_t clone_obj
uint32_t handle
Definition zend_types.h:558
Definition cdb.h:26
ZEND_API zend_string * zend_strpprintf(size_t max_len, const char *format,...)
Definition zend.c:353
ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format,...)
Definition zend.c:1772
ZEND_API ZEND_COLD void zend_error(int type, const char *format,...)
Definition zend.c:1666
#define ZEND_TSRMLS_CACHE_UPDATE()
Definition zend.h:69
#define INTERNAL_FUNCTION_PARAMETERS
Definition zend.h:49
#define ZEND_TSRMLS_CACHE_DEFINE()
Definition zend.h:68
#define INTERNAL_FUNCTION_PARAM_PASSTHRU
Definition zend.h:50
ZEND_API zend_result add_next_index_stringl(zval *arg, const char *str, size_t length)
Definition zend_API.c:2195
ZEND_API zend_result object_init_ex(zval *arg, zend_class_entry *class_type)
Definition zend_API.c:1849
ZEND_API ZEND_COLD void zend_argument_error(zend_class_entry *error_ce, uint32_t arg_num, const char *format,...)
Definition zend_API.c:413
ZEND_API void add_index_str(zval *arg, zend_ulong index, zend_string *str)
Definition zend_API.c:2078
ZEND_API zend_result zend_parse_parameters(uint32_t num_args, const char *type_spec,...)
Definition zend_API.c:1300
ZEND_API void object_properties_init(zend_object *object, zend_class_entry *class_type)
Definition zend_API.c:1688
ZEND_API ZEND_COLD void zend_argument_must_not_be_empty_error(uint32_t arg_num)
Definition zend_API.c:443
ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format,...)
Definition zend_API.c:433
ZEND_API zend_result add_next_index_string(zval *arg, const char *str)
Definition zend_API.c:2186
ZEND_API zend_result zend_parse_parameters_ex(int flags, uint32_t num_args, const char *type_spec,...)
Definition zend_API.c:1287
#define ZEND_PARSE_PARAMETERS_START_EX(flags, min_num_args, max_num_args)
Definition zend_API.h:1589
#define ZEND_NUM_ARGS()
Definition zend_API.h:530
#define ZEND_PARSE_PARAMS_QUIET
Definition zend_API.h:361
#define ZEND_PARSE_PARAMETERS_END()
Definition zend_API.h:1641
#define RETURN_FALSE
Definition zend_API.h:1058
#define ZEND_DECLARE_MODULE_GLOBALS(module_name)
Definition zend_API.h:268
#define Z_PARAM_OPTIONAL
Definition zend_API.h:1667
#define ZEND_GET_MODULE(name)
Definition zend_API.h:241
#define zend_parse_parameters_none()
Definition zend_API.h:353
#define ZEND_PARSE_PARAMETERS_END_EX(failure)
Definition zend_API.h:1630
#define Z_PARAM_STR(dest)
Definition zend_API.h:2086
#define ZEND_PARSE_PARAMETERS_START(min_num_args, max_num_args)
Definition zend_API.h:1620
#define ZEND_END_MODULE_GLOBALS(module_name)
Definition zend_API.h:248
#define Z_PARAM_ARRAY_HT_OR_STR(dest_ht, dest_str)
Definition zend_API.h:2151
#define Z_PARAM_LONG(dest)
Definition zend_API.h:1896
#define RETURN_THROWS()
Definition zend_API.h:1060
#define RETURN_STR(s)
Definition zend_API.h:1039
#define RETVAL_BOOL(b)
Definition zend_API.h:1009
#define Z_PARAM_OBJECT_OF_CLASS(dest, _ce)
Definition zend_API.h:1976
#define RETURN_TRUE
Definition zend_API.h:1059
#define ZEND_BEGIN_MODULE_GLOBALS(module_name)
Definition zend_API.h:246
#define array_init(arg)
Definition zend_API.h:537
#define efree(ptr)
Definition zend_alloc.h:155
#define pefree(ptr, persistent)
Definition zend_alloc.h:191
#define pecalloc(nmemb, size, persistent)
Definition zend_alloc.h:200
struct _zval_struct zval
strcmp(string $string1, string $string2)
zend_string_release_ex(func->internal_function.function_name, 0)
#define strcasecmp(s1, s2)
#define E_NOTICE
Definition zend_errors.h:26
#define E_WARNING
Definition zend_errors.h:24
#define E_DEPRECATED
Definition zend_errors.h:37
#define LOCK_EX
#define LOCK_SH
union _zend_function zend_function
#define EG(v)
ZEND_API void ZEND_FASTCALL zend_hash_destroy(HashTable *ht)
Definition zend_hash.c:1727
ZEND_API zval *ZEND_FASTCALL zend_hash_str_find(const HashTable *ht, const char *str, size_t len)
Definition zend_hash.c:2689
ZEND_API zend_result ZEND_FASTCALL zend_hash_move_forward_ex(HashTable *ht, HashPosition *pos)
Definition zend_hash.c:2773
ZEND_API void ZEND_FASTCALL zend_hash_internal_pointer_reset_ex(HashTable *ht, HashPosition *pos)
Definition zend_hash.c:2733
ZEND_API zval *ZEND_FASTCALL zend_hash_get_current_data_ex(HashTable *ht, HashPosition *pos)
Definition zend_hash.c:2915
ZEND_API void ZEND_FASTCALL zend_hash_apply_with_argument(HashTable *ht, apply_func_arg_t apply_func, void *argument)
Definition zend_hash.c:2099
ZEND_API zval *ZEND_FASTCALL zend_hash_add_new(HashTable *ht, zend_string *key, zval *pData)
Definition zend_hash.c:1007
ZEND_API zend_result ZEND_FASTCALL zend_hash_del(HashTable *ht, zend_string *key)
Definition zend_hash.c:1534
#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent)
Definition zend_hash.h:108
#define ZEND_HASH_MAP_FOREACH_VAL(ht, _val)
Definition zend_hash.h:1310
#define ZEND_HASH_APPLY_REMOVE
Definition zend_hash.h:147
#define ZEND_HASH_APPLY_KEEP
Definition zend_hash.h:146
#define ZEND_HASH_FOREACH_END()
Definition zend_hash.h:1086
#define UNREGISTER_INI_ENTRIES()
Definition zend_ini.h:204
#define REGISTER_INI_ENTRIES()
Definition zend_ini.h:203
#define DISPLAY_INI_ENTRIES()
Definition zend_ini.h:205
#define ZEND_INI_MH(name)
Definition zend_ini.h:30
ZEND_API zend_resource * zend_register_persistent_resource(const char *key, size_t key_len, void *rsrc_pointer, int rsrc_type)
Definition zend_list.c:342
ZEND_API int zend_register_list_destructors_ex(rsrc_dtor_func_t ld, rsrc_dtor_func_t pld, const char *type_name, int module_number)
Definition zend_list.c:265
int32_t zend_long
Definition zend_long.h:42
struct _zend_string zend_string
#define STANDARD_MODULE_HEADER
struct _zend_module_entry zend_module_entry
#define STANDARD_MODULE_PROPERTIES_EX
ZEND_API zend_result zend_std_cast_object_tostring(zend_object *readobj, zval *writeobj, int type)
ZEND_API int zend_objects_not_comparable(zval *o1, zval *o2)
ZEND_API const zend_object_handlers std_object_handlers
ZEND_API void ZEND_FASTCALL zend_object_std_init(zend_object *object, zend_class_entry *ce)
ZEND_API void zend_object_std_dtor(zend_object *object)
#define ZEND_FALLTHROUGH
#define EXPECTED(condition)
#define zend_always_inline
#define XtOffsetOf(s_type, field)
#define ZEND_ASSERT(c)
#define UNEXPECTED(condition)
struct _zend_class_entry zend_class_entry
struct _zend_object zend_object
#define ZSTR_IS_INTERNED(s)
Definition zend_string.h:84
#define ZSTR_VAL(zstr)
Definition zend_string.h:68
#define ZSTR_LEN(zstr)
Definition zend_string.h:69
#define Z_TYPE_P(zval_p)
Definition zend_types.h:660
#define IS_FALSE
Definition zend_types.h:602
#define ZVAL_LONG(z, l)
struct _zend_resource zend_resource
Definition zend_types.h:99
struct _zend_array HashTable
Definition zend_types.h:386
#define GC_MAKE_PERSISTENT_LOCAL(p)
#define IS_NULL
Definition zend_types.h:601
@ FAILURE
Definition zend_types.h:61
#define IS_LONG
Definition zend_types.h:604
#define ZVAL_COPY(z, v)
uint32_t HashPosition
Definition zend_types.h:548
ZEND_RESULT_CODE zend_result
Definition zend_types.h:64
#define Z_RES_P(zval_p)
struct _zend_object_handlers zend_object_handlers
Definition zend_types.h:88
ZEND_API void zval_ptr_dtor(zval *zval_ptr)
zval * return_value
zend_string * name
fbc internal_function handler(call, ret)
bool result
value