diff --git a/ext/dba/dba.c b/ext/dba/dba.c
index 86b99ad4bb6f0..107541bd2efa3 100644
--- a/ext/dba/dba.c
+++ b/ext/dba/dba.c
@@ -262,9 +262,10 @@ static void dba_close(dba_info *info)
 	if (info->hnd) {
 		info->hnd->close(info);
 	}
-	if (info->path) {
-		pefree(info->path, info->flags&DBA_PERSISTENT);
-	}
+	ZEND_ASSERT(info->path);
+	zend_string_release_ex(info->path, info->flags&DBA_PERSISTENT);
+	info->path = NULL;
+
 	if (info->fp && info->fp != info->lock.fp) {
 		if (info->flags & DBA_PERSISTENT) {
 			php_stream_pclose(info->fp);
@@ -431,7 +432,7 @@ static void php_dba_update(INTERNAL_FUNCTION_PARAMETERS, int mode)
 /* }}} */
 
 /* {{{ php_find_dbm */
-static dba_info *php_dba_find(const char* path)
+static dba_info *php_dba_find(const zend_string *path)
 {
 	zend_resource *le;
 	dba_info *info;
@@ -444,7 +445,7 @@ static dba_info *php_dba_find(const char* path)
 		}
 		if (le->type == le_db || le->type == le_pdb) {
 			info = (dba_info *)(le->ptr);
-			if (!strcmp(info->path, path)) {
+			if (zend_string_equals(path, info->path)) {
 				return (dba_info *)(le->ptr);
 			}
 		}
@@ -454,6 +455,20 @@ static dba_info *php_dba_find(const char* path)
 }
 /* }}} */
 
+static zend_always_inline zend_string *php_dba_zend_string_dup_safe(zend_string *s, bool persistent)
+{
+	if (ZSTR_IS_INTERNED(s) && !persistent) {
+		return s;
+	} else {
+		zend_string *duplicated_str = zend_string_init(ZSTR_VAL(s), ZSTR_LEN(s), persistent);
+		if (persistent) {
+			GC_MAKE_PERSISTENT_LOCAL(duplicated_str);
+		}
+		return duplicated_str;
+	}
+}
+
+
 #define FREE_PERSISTENT_RESOURCE_KEY() if (persistent_resource_key) {zend_string_release_ex(persistent_resource_key, false);}
 
 /* {{{ php_dba_open */
@@ -467,7 +482,6 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, bool persistent)
 	const char *file_mode;
 	const char *lock_file_mode = NULL;
 	int persistent_flag = persistent ? STREAM_OPEN_PERSISTENT : 0;
-	zend_string *opened_path = NULL;
 	char *lock_name;
 #ifdef PHP_WIN32
 	bool restarted = 0;
@@ -724,7 +738,7 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, bool persistent)
 
 	info = pemalloc(sizeof(dba_info), persistent);
 	memset(info, 0, sizeof(dba_info));
-	info->path = pestrdup(ZSTR_VAL(path), persistent);
+	info->path = php_dba_zend_string_dup_safe(path, persistent);
 	info->mode = modenr;
 	info->file_permission = permission;
 	info->map_size = map_size;
@@ -753,8 +767,9 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, bool persistent)
 		if (is_db_lock) {
 			lock_name = ZSTR_VAL(path);
 		} else {
-			spprintf(&lock_name, 0, "%s.lck", info->path);
+			spprintf(&lock_name, 0, "%s.lck", ZSTR_VAL(info->path));
 			if (!strcmp(file_mode, "r")) {
+				zend_string *opened_path = NULL;
 				/* when in read only mode try to use existing .lck file first */
 				/* do not log errors for .lck file while in read only mode on .lck file */
 				lock_file_mode = "rb";
@@ -769,13 +784,17 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, bool persistent)
 			}
 		}
 		if (!info->lock.fp) {
+			zend_string *opened_path = NULL;
 			info->lock.fp = php_stream_open_wrapper(lock_name, lock_file_mode, STREAM_MUST_SEEK|REPORT_ERRORS|IGNORE_PATH|persistent_flag, &opened_path);
 			if (info->lock.fp) {
 				if (is_db_lock) {
+					ZEND_ASSERT(opened_path);
 					/* replace the path info with the real path of the opened file */
-					pefree(info->path, persistent);
-					info->path = pestrndup(ZSTR_VAL(opened_path), ZSTR_LEN(opened_path), persistent);
+					zend_string_release(info->path);
+					info->path = php_dba_zend_string_dup_safe(opened_path, persistent);
 				}
+			}
+			if (opened_path) {
 				zend_string_release_ex(opened_path, 0);
 			}
 		}
@@ -801,7 +820,7 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, bool persistent)
 		if (info->lock.fp && is_db_lock) {
 			info->fp = info->lock.fp; /* use the same stream for locking and database access */
 		} else {
-			info->fp = php_stream_open_wrapper(info->path, file_mode, STREAM_MUST_SEEK|REPORT_ERRORS|IGNORE_PATH|persistent_flag, NULL);
+			info->fp = php_stream_open_wrapper(ZSTR_VAL(info->path), file_mode, STREAM_MUST_SEEK|REPORT_ERRORS|IGNORE_PATH|persistent_flag, NULL);
 		}
 		if (!info->fp) {
 			dba_close(info);
@@ -1207,7 +1226,7 @@ PHP_FUNCTION(dba_list)
 		}
 		if (le->type == le_db || le->type == le_pdb) {
 			info = (dba_info *)(le->ptr);
-			add_index_string(return_value, i, info->path);
+			add_index_str(return_value, i, zend_string_copy(info->path));
 		}
 	}
 }
diff --git a/ext/dba/dba_cdb.c b/ext/dba/dba_cdb.c
index 5af9121b565a6..d5af1b8cce249 100644
--- a/ext/dba/dba_cdb.c
+++ b/ext/dba/dba_cdb.c
@@ -73,7 +73,7 @@ DBA_OPEN_FUNC(cdb)
 			make = 0;
 			file = info->fp;
 #else
-			file = VCWD_OPEN(info->path, O_RDONLY);
+			file = VCWD_OPEN(ZSTR_VAL(info->path), O_RDONLY);
 			if (file < 0) {
 				*error = "Unable to open file";
 				return FAILURE;
diff --git a/ext/dba/dba_db1.c b/ext/dba/dba_db1.c
index 3a95cea460c14..57dfab38f13b7 100644
--- a/ext/dba/dba_db1.c
+++ b/ext/dba/dba_db1.c
@@ -61,7 +61,7 @@ DBA_OPEN_FUNC(db1)
 			return FAILURE; /* not possible */
 	}
 
-	db = dbopen((char *)info->path, gmode, filemode, DB_HASH, NULL);
+	db = dbopen((char *)ZSTR_VAL(info->path), gmode, filemode, DB_HASH, NULL);
 
 	if (db == NULL) {
 		return FAILURE;
diff --git a/ext/dba/dba_db2.c b/ext/dba/dba_db2.c
index 8f6d47a9239c9..86306bd59a2b8 100644
--- a/ext/dba/dba_db2.c
+++ b/ext/dba/dba_db2.c
@@ -41,7 +41,7 @@ DBA_OPEN_FUNC(db2)
 	int gmode = 0;
 	int filemode = info->file_permission;
 	struct stat check_stat;
-	int s = VCWD_STAT(info->path, &check_stat);
+	int s = VCWD_STAT(ZSTR_VAL(info->path), &check_stat);
 
 	if (!s && !check_stat.st_size) {
 		info->mode = DBA_TRUNC; /* force truncate */
@@ -61,7 +61,7 @@ DBA_OPEN_FUNC(db2)
 		return FAILURE;/* not possible */
 	}
 
-	if (db_open(info->path, type, gmode, filemode, NULL, NULL, &dbp)) {
+	if (db_open(ZSTR_VAL(info->path), type, gmode, filemode, NULL, NULL, &dbp)) {
 		return FAILURE;
 	}
 
diff --git a/ext/dba/dba_db3.c b/ext/dba/dba_db3.c
index d9e948a623f50..5d36d86e00808 100644
--- a/ext/dba/dba_db3.c
+++ b/ext/dba/dba_db3.c
@@ -53,7 +53,7 @@ DBA_OPEN_FUNC(db3)
 	int gmode = 0, err;
 	int filemode = info->file_permission;
 	struct stat check_stat;
-	int s = VCWD_STAT(info->path, &check_stat);
+	int s = VCWD_STAT(ZSTR_VAL(info->path), &check_stat);
 
 	if (!s && !check_stat.st_size) {
 		info->mode = DBA_TRUNC; /* force truncate */
@@ -81,9 +81,9 @@ DBA_OPEN_FUNC(db3)
 	    dbp->set_errcall(dbp, php_dba_db3_errcall_fcn);
 		if(
 #if (DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1))
-			(err=dbp->open(dbp, 0, info->path, NULL, type, gmode, filemode)) == 0) {
+			(err=dbp->open(dbp, 0, ZSTR_VAL(info->path), NULL, type, gmode, filemode)) == 0) {
 #else
-			(err=dbp->open(dbp, info->path, NULL, type, gmode, filemode)) == 0) {
+			(err=dbp->open(dbp, ZSTR_VAL(info->path), NULL, type, gmode, filemode)) == 0) {
 #endif
 			dba_db3_data *data;
 
diff --git a/ext/dba/dba_db4.c b/ext/dba/dba_db4.c
index 3de66a4274432..a2dbd5dafa1e2 100644
--- a/ext/dba/dba_db4.c
+++ b/ext/dba/dba_db4.c
@@ -67,7 +67,7 @@ DBA_OPEN_FUNC(db4)
 	int gmode = 0, err;
 	int filemode = info->file_permission;
 	struct stat check_stat;
-	int s = VCWD_STAT(info->path, &check_stat);
+	int s = VCWD_STAT(ZSTR_VAL(info->path), &check_stat);
 
 #if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR <= 7)  /* Bug 51086 */
 	if (!s && !check_stat.st_size) {
@@ -110,9 +110,9 @@ DBA_OPEN_FUNC(db4)
 	    dbp->set_errcall(dbp, php_dba_db4_errcall_fcn);
 	    if (
 #if (DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1))
-			(err=dbp->open(dbp, 0, info->path, NULL, type, gmode, filemode)) == 0) {
+			(err=dbp->open(dbp, 0, ZSTR_VAL(info->path), NULL, type, gmode, filemode)) == 0) {
 #else
-			(err=dbp->open(dbp, info->path, NULL, type, gmode, filemode)) == 0) {
+			(err=dbp->open(dbp, ZSTR_VAL(info->path), NULL, type, gmode, filemode)) == 0) {
 #endif
 			dba_db4_data *data;
 
diff --git a/ext/dba/dba_dbm.c b/ext/dba/dba_dbm.c
index afa645cb2fe70..88a8959082709 100644
--- a/ext/dba/dba_dbm.c
+++ b/ext/dba/dba_dbm.c
@@ -36,7 +36,7 @@
 #include <fcntl.h>
 
 #define TRUNC_IT(extension, mode) \
-	snprintf(buf, MAXPATHLEN, "%s" extension, info->path); \
+	snprintf(buf, MAXPATHLEN, "%s" extension, ZSTR_VAL(info->path)); \
 	buf[MAXPATHLEN-1] = '\0'; \
 	if((fd = VCWD_OPEN_MODE(buf, O_CREAT | mode | O_WRONLY, filemode)) == -1) \
 		return FAILURE; \
@@ -67,7 +67,7 @@ DBA_OPEN_FUNC(dbm)
 		TRUNC_IT(".dir", 0);
 	}
 
-	if(dbminit((char *) info->path) == -1) {
+	if(dbminit((char *) ZSTR_VAL(info->path)) == -1) {
 		return FAILURE;
 	}
 
diff --git a/ext/dba/dba_gdbm.c b/ext/dba/dba_gdbm.c
index c3fbb5bf21e18..0781e1fb1a76f 100644
--- a/ext/dba/dba_gdbm.c
+++ b/ext/dba/dba_gdbm.c
@@ -46,7 +46,7 @@ DBA_OPEN_FUNC(gdbm)
 	if(gmode == -1)
 		return FAILURE; /* not possible */
 
-	dbf = gdbm_open(info->path, /* int block_size */ 0, gmode, filemode, NULL);
+	dbf = gdbm_open(ZSTR_VAL(info->path), /* int block_size */ 0, gmode, filemode, NULL);
 
 	if(dbf) {
 		info->dbf = pemalloc(sizeof(dba_gdbm_data), info->flags&DBA_PERSISTENT);
diff --git a/ext/dba/dba_lmdb.c b/ext/dba/dba_lmdb.c
index 1645453324525..f147f4c810dee 100644
--- a/ext/dba/dba_lmdb.c
+++ b/ext/dba/dba_lmdb.c
@@ -81,7 +81,7 @@ DBA_OPEN_FUNC(lmdb)
 		}
 	}
 
-	rc = mdb_env_open(env, info->path, flags, mode);
+	rc = mdb_env_open(env, ZSTR_VAL(info->path), flags, mode);
 	if (rc) {
 		/* If this function [mdb_env_open()] fails, mdb_env_close() must be called to discard the MDB_env handle.
 		 * http://www.lmdb.tech/doc/group__mdb.html#ga32a193c6bf4d7d5c5d579e71f22e9340 */
diff --git a/ext/dba/dba_ndbm.c b/ext/dba/dba_ndbm.c
index d872add48e6ab..758fcd1e77172 100644
--- a/ext/dba/dba_ndbm.c
+++ b/ext/dba/dba_ndbm.c
@@ -52,7 +52,7 @@ DBA_OPEN_FUNC(ndbm)
 			return FAILURE; /* not possible */
 	}
 
-	dbf = dbm_open(info->path, gmode, filemode);
+	dbf = dbm_open(ZSTR_VAL(info->path), gmode, filemode);
 
 	pinfo->dbf = dbf;
 	return SUCCESS;
diff --git a/ext/dba/dba_qdbm.c b/ext/dba/dba_qdbm.c
index d06af20659909..d70885754bedd 100644
--- a/ext/dba/dba_qdbm.c
+++ b/ext/dba/dba_qdbm.c
@@ -37,16 +37,16 @@ DBA_OPEN_FUNC(qdbm)
 
 	switch(info->mode) {
 		case DBA_READER:
-			dbf = dpopen(info->path, DP_OREADER, 0);
+			dbf = dpopen(ZSTR_VAL(info->path), DP_OREADER, 0);
 			break;
 		case DBA_WRITER:
-			dbf = dpopen(info->path, DP_OWRITER, 0);
+			dbf = dpopen(ZSTR_VAL(info->path), DP_OWRITER, 0);
 			break;
 		case DBA_CREAT:
-			dbf = dpopen(info->path, DP_OWRITER | DP_OCREAT, 0);
+			dbf = dpopen(ZSTR_VAL(info->path), DP_OWRITER | DP_OCREAT, 0);
 			break;
 		case DBA_TRUNC:
-			dbf = dpopen(info->path, DP_OWRITER | DP_OCREAT | DP_OTRUNC, 0);
+			dbf = dpopen(ZSTR_VAL(info->path), DP_OWRITER | DP_OCREAT | DP_OTRUNC, 0);
 			break;
 		default:
 			return FAILURE;
diff --git a/ext/dba/dba_tcadb.c b/ext/dba/dba_tcadb.c
index 23c9e2d1d363d..b085558a71133 100644
--- a/ext/dba/dba_tcadb.c
+++ b/ext/dba/dba_tcadb.c
@@ -39,16 +39,16 @@ DBA_OPEN_FUNC(tcadb)
 	if (tcadb) {
 		switch(info->mode) {
 			case DBA_READER:
-				spprintf(&path_string, 0, "%s#mode=r", info->path);
+				spprintf(&path_string, 0, "%s#mode=r", ZSTR_VAL(info->path));
 				break;
 			case DBA_WRITER:
-				spprintf(&path_string, 0, "%s#mode=w", info->path);
+				spprintf(&path_string, 0, "%s#mode=w", ZSTR_VAL(info->path));
 				break;
 			case DBA_CREAT:
-				spprintf(&path_string, 0, "%s#mode=wc", info->path);
+				spprintf(&path_string, 0, "%s#mode=wc", ZSTR_VAL(info->path));
 				break;
 			case DBA_TRUNC:
-				spprintf(&path_string, 0, "%s#mode=wct", info->path);
+				spprintf(&path_string, 0, "%s#mode=wct", ZSTR_VAL(info->path));
 				break;
 			default:
 				tcadbdel(tcadb);
diff --git a/ext/dba/php_dba.h b/ext/dba/php_dba.h
index d6a86f76b271d..30742661c3bba 100644
--- a/ext/dba/php_dba.h
+++ b/ext/dba/php_dba.h
@@ -38,7 +38,7 @@ typedef struct dba_lock {
 typedef struct dba_info {
 	/* public */
 	void *dbf;               /* ptr to private data or whatever */
-	char *path;
+	zend_string *path;
 	dba_mode_t mode;
 	php_stream *fp;  /* this is the database stream for builtin handlers */
 	int fd;