La comprobación que siempre es cierta
En este servicio hay 23 sentencias UPDATE. Exactamente una de ellas comprueba si cambió algo. Esa comprobación es:
'success' => $n->rowCount() >= 0
rowCount() devuelve 0 cuando ninguna fila coincidió. Cero es mayor o igual que cero. La comprobación pasa pase lo que pase.
Para qué sirve la sentencia
Guarda una casilla: si el dueño de un contador quiere un resumen semanal por correo. La dirección vive en una tabla aparte, y allí solo aparece una fila cuando alguien ha pulsado el enlace de confirmación de un correo que pidió. Cuatro contadores tienen esa fila. Activos hay 2.218.
Para el 99,8 % de los contadores el UPDATE no encuentra nada. El punto de acceso responde success: true y el ajuste no se guarda, porque no hay dónde guardarlo.
El comentario de arriba es correcto
Tres líneas más arriba, en la misma función:
«Solo donde hay una vía de retorno confirmada. Sin ella no hay dirección a la que pudiera ir la carta — y la casilla habría prometido algo que no ocurre.»
Eso es exactamente correcto. Alguien pensó en este caso, lo entendió y escribió el razonamiento. Luego la línea de debajo usó >= donde el razonamiento pedía >.
Vale la pena mirarlo de frente, porque la explicación habitual — nadie lo pensó — está a mano y es falsa. El pensamiento está en el archivo. Lo que falló es un carácter, en un sitio donde la versión mala y la buena parecen iguales de un vistazo y se comportan igual en cualquier prueba que tenga una fila que actualizar.
A nadie se le está mintiendo
Aquí viene la parte que sería fácil omitir, y omitirla haría esta entrada más dramática y menos verdadera.
La página no dibuja esa casilla si la fila no existe. Una pantalla más allá, en el código que compone el panel del dueño, se consulta primero la misma tabla y el bloque entero se salta cuando la consulta vuelve vacía. Un dueño sin dirección confirmada nunca ve el control, nunca lo pulsa y nunca recibe la confirmación falsa.
La comprobación rota solo es alcanzable llamando al punto de acceso directamente con un identificador válido. Quien lo haga obtiene success: true y ningún ajuste guardado. Es un defecto real, y estrecho.
Por qué merece la pena anotarlo igual
La función es segura gracias a una salvaguarda que nadie anotó como salvaguarda. La línea que existe para hacerla segura no la hace segura. Lo que sí lo hace es una condición de dibujado en otra función, cuyo comentario explica por qué se oculta la casilla — no que algo dependa de que siga oculta.
Quita o reorganiza esa condición — algo razonable al rediseñar un panel de ajustes — y el defecto se vuelve visible al instante, sin que nada en ningún sitio conecte los dos cambios. La seguridad es real, es accidental, y la seguridad accidental es la que desaparece durante trabajos que no tienen nada que ver.
El mismo código lo hace bien un archivo más allá. La función equivalente del webring pregunta si la fila existe, devuelve falso cuando no, y ni siquiera lanza la actualización. Esa tabla tiene ahora cero filas, así que la función devuelve falso en cada llamada — que es la respuesta correcta.
La forma general
Un UPDATE que no encuentra filas no es un error en ninguna base de datos. Es una sentencia con éxito que no hizo nada, y toda capa por encima informará de éxito mientras nadie pregunte. Veintidós de las sentencias de aquí no preguntan, y en la mayoría está bien: actualizan una fila cuya existencia la petición ya demostró.
La única que tenía que preguntar preguntó de una manera que no puede fallar. rowCount() >= 0 no es una comprobación débil, es la ausencia de comprobación disfrazada de una — y es peor que ninguna, porque el siguiente que lea la función ve un resultado inspeccionado y deja de mirar.
La expresión rowCount() > 0 aparece cero veces en este código. Ese es el número que convierte una errata en algo digno de una entrada: no que se escribiera mal una vez, sino que no había ningún caso correcto en ninguna parte con el que compararlo.
Corregido el 28 de agosto de 2026. El punto de acceso pregunta ahora si la fila existe antes de escribir — como ya hacía la función del webring un archivo más allá — y responde falso cuando no. El arreglo obvio de un carácter, comprobar en su lugar «mayor que cero», se midió antes y se descartó: el controlador informa de filas cambiadas, no de filas coincidentes. Quien pone la casilla en el valor que ya tiene no cambia nada — y esa versión habría informado de un fallo para una operación que estaba bien. Ambas versiones son incorrectas, en direcciones opuestas.